C++ Password program, string wont delete last character when backspacing - c++

So I am creating a simple password program that asks you for an input but masks it with asterisks (*). The code I have works, but when I backspace the string returned is like I had never backspaced.
What I would Type:
12345
I would hit the backspace twice, and the string would look like this:
123
But when I hit enter, it returns this:
1234
Here is the code that I have.
#include <iostream>
#include <string>
#include <conio.h> //Regular includes.
using namespace std;
string Encrypted_Text(int a) { //Code for the password masker
string Pwd = " "; //Creates password variable.
char Temp; //Temporary variable that stores current keystroke.
int Length = 0; //Controls how long that password is.
for (;;) { //Loops until the password is above the min. amount.
Temp = _getch(); //Gets keystroke.
while (Temp != 13) { //Loops until enter is hit.
Length++; //Increases length of password.
Pwd.push_back(Temp); //Adds newly typed key on to the string.
cout << "*";
Temp = _getch(); // VV This is were the error is VV
if (Temp == 8) { // detects when you hit the backspace key.
Pwd.pop_back; //removes the last character on string.
cout << "\b "; //Deletes the last character on console.
Length--; //decreases the length of the string.
}
}
if (Length < a) { //Tests to see if the password is long enough.
cout << "\nInput Is To Short.\n";
Pwd = "";
Temp = 0;
Length = 0;
}
else {
break;
}
}
return Pwd; //Returns password.
}
And in my main function i have this:
string Test = Encrypted_Text(5);
cout << "you entered : " << Test;

In your code you push_back whatever character you get. Only after that you remove a character if it is a backspace. This is why it doesn't work.
You need to first check for special characters and only if it is not one of those you add the character.
Also there is no need to have the Length variable since std::string knows its length and you can get it from there.

Related

C++ Need some advices with Pig Latin string

I need to write a sentence in Pig Latin form and I am almost done it successfuly except for 1 case and I almost give up
for example :
If my word starts at a\e\o\u\i the word will look like easy -> easyway , apple -> appleway
and if it doesnt start with a letter that I wrote above
it will look like that: box -> oxbay , king -> ingkay
I succeed with the bolded part but in the first part with a\e\o\u\i letter at the beginning , I dont know where to put the w before and need some help with it
This is my code , thanks in advance
#include <iostream>
//Since those are used in ALL function of program, it wont hurt to set it to global
//Else it is considered EVIL to declare global variables
const int maxLine = 100;
char phraseLine[maxLine] = { '\0' };
void pigLatinString();
using namespace std;
void main()
{
// Displayed heading of program
cout << "* You will be prompted to enter a string of *" << endl;
cout << "* words. The string will be converted into *" << endl;
cout << "* Pig Latin and the results displayed. *" << endl;
cout << "* Enter as many strings as you would like. *" << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
cout << endl;
// This is the main loop. Continue executing until the user hits 'enter' to quit.
while (phraseLine[0] != '\0')
{
// Display the word (s) entered by the user
cout << "You entered the following: " << phraseLine << endl;
// Display the word (s) in Pig Latin
cout << "The same phrase in Pig latin is: ";
pigLatinString();
cout << endl;
//prompt the user for a group of words or press enter to quit
cout << "Please enter a word or group of words. (Press enter to quit)\n";
cin.getline(phraseLine, 100, '\n');
}
return;
}
void pigLatinString() //phraseLine is a cstring for the word, maxline is max length of line
{ //variable declarations
char tempConsonant[10];
tempConsonant[0] = '\0';
int numberOfConsonants = 0;
char previousCharacter = ' ';
char currentCharacter = ' ';
bool isInWord = 0;
// for loop checking each index to the end of whatever is typed in
for (int i = 0; i < maxLine; i++)
{
//checking for the end of the phraseline
if (phraseLine[i] == '\0')
{//checking to see if it's in the word
if (isInWord)
{//checking to see that there wasn't a space ahead of the word and then sending the cstring + ay to the console
if (previousCharacter != ' ')
cout << tempConsonant << "ay" << endl;
}
return;
}
// this covers the end of the word condition
if (isInWord)
{// covers the condition of index [i] being the space at the end of the word
if (phraseLine[i] == ' ')
{
// spits out pig latin word, gets you out of the word, flushes the temp consonants array and resets the # of consonants to 0
cout << tempConsonant << "ay";
isInWord = 0;
tempConsonant[0] = '\0';
numberOfConsonants = 0;
}
cout << phraseLine[i] ;
}
else
{//this covers for the first vowel that makes the switch
if (phraseLine[i] != ' ')
{// sets the c string to what is in the phraseline at the time and makes it capitalized
char currentCharacter = phraseLine[i];
currentCharacter = toupper(currentCharacter);
// this takes care of the condition that currentCharacter is not a vowel
if ((currentCharacter != 'A') && (currentCharacter != 'E') &&
(currentCharacter != 'I') && (currentCharacter != 'O') && (currentCharacter != 'U'))
//this sets the array to temporarily hold the consonants for display before the 'ay'
{//this sets the null operator at the end of the c string and looks for the next consonant
tempConsonant[numberOfConsonants] = phraseLine[i];
tempConsonant[numberOfConsonants + 1] = '\0';
numberOfConsonants++;
}
else
{// this sets the boolean isInWord to true and displays the phraseline
isInWord = 1;
cout << phraseLine[i];
}
}
else
{
cout << phraseLine[i] ;
}
}
previousCharacter = phraseLine[i];
}
return;
}
You have two conditions to consider. if your word starts with a vowel, just add "way" to the end of the word, else move the first letter and add "ay" to the end.
This is a task that can be made a lot simpler by using std::string instead of C-strings. This is because you are now no longer concerned with exceeding your length or losing the null character. It also allows easier access to the Standard Library algorithms.
#include <algorithm>
#include <iostream>
#include <string>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiou");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::cout << make_pig_latin("apple") << '\n'
<< make_pig_latin("box") << '\n'
<< make_pig_latin("king") << '\n'
<< make_pig_latin("easy") << '\n';
}
The function above highlights how you can go about structuring your conversion. You just need to know if your word starts with a vowel or not, and take the appropriate action.
Output:
appleway
oxbay
ingkay
easyway
I did not get the impression that you have to care about words like 'phone'.
Looking through your code, you should try to do a better job at separating your concerns. Pig Latin is easier done one word at a time, but you have string splitting code and a lot of "not Pig Latin" code in your Pig Latin function. Your main can handle getting input. You should probably have a separate function to break the line up into individual words, using std::vector to hold the words would be best since it can grow on demand and doesn't have to know a specific capacity up front. You then iterate through your array of words and translate them individually. Depending on what your actual requirements are, it's possible that you don't even have to store the translated words, just print them directly to the screen.
Here's the same program, but now it can separate words. Note how the pig latin function doesn't have to change (much, I added upper-case vowels just because I didn't want to bothered converting words) in order for the added functionality to be added.
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
std::string make_pig_latin(const std::string& word) {
std::string vowels("aeiouAEIOU");
std::string newWord(word);
if (newWord.find_first_not_of(vowels) == 0) {
// Word starts with a consanant
std::rotate(newWord.begin(), newWord.begin() + 1, newWord.end());
newWord += "ay";
} else {
newWord += "way";
}
return newWord;
}
int main() {
std::string phrase(
"A sentence where I say words like apple box easy king and ignore "
"punctuation");
std::istringstream sin(phrase);
std::vector<std::string> words(std::istream_iterator<std::string>(sin), {});
for (auto i : words) {
std::cout << make_pig_latin(i) << ' ';
}
}
Output:
Away entencesay hereway Iway aysay ordsway ikelay appleway oxbay easyway ingkay andway ignoreway unctuationpay

Q: C++ - Reversing a string (sentence and word) using a class

For my code, I am trying to create a class with two functions that:
Display a cstring where each word is reversed
Display an entire cstring reversed
My two test sentences are "Hi There" and "To Be", so the output is:
erehT iH
eB oT
iH erehT
oT eB
Here is my code:
#include <iostream>
#include <cstring>
using namespace std;
class cStringType {
public:
char sentenceInput[80]; //Member variable
void reverse_sentence(); //Member function
void reverse_words(); //Member function
}; //Bottom of cStringType
int main()
{
cStringType sentence1, sentence2;
//Objects declared of cStringType
cout << "Please enter a sentence!\n" << endl;
cin.get(sentence1.sentenceInput, 79, '\n');
cin.ignore(80, '\n');
cout << "\nPlease enter another sentence!\n" << endl;
cin.get(sentence2.sentenceInput, 79, '\n');
cout << "\nThe first sentence reversed: ";
sentence1.reverse_sentence();
cout << endl;
cout << "The second sentence where each word is reversed: ";
sentence2.reverse_words();
cout << endl;
cout << endl;
cout << "The first sentence where each word is reversed: ";
sentence1.reverse_words();
cout << endl;
cout << "The second sentence reversed: ";
sentence2.reverse_sentence();
cout << endl;
return 0;
}
void cStringType::reverse_sentence()
{
char reverse_sentence;
//Reverse entire sentence using loop
for (int i = 0; i < strlen(sentenceInput) / 2; i++)
{
//Reverse the sentence using the length of the
//variable in the class
reverse_sentence = sentenceInput[i];
//First get the user input
//Set your variable equal to the variable in the class
sentenceInput[i] = sentenceInput[strlen(sentenceInput) - i - 1];
//Then reverse the characters and word order
//Starts from the last character in the array
//and goes backwards to 0
sentenceInput[strlen(sentenceInput) - i - 1] = reverse_sentence;
//Set the variable equal to the result
//sentenceInput is now the reverse of the user input in main
}
cout << sentenceInput << endl;
//Output of the new sentence
}
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
for (beginning = j, end = i - 1;
beginning < (i + j) / 2; beginning++, end--)
//j is the beginning of the array; increases
//i is the end of the array; decreases
{
reverse_words = sentenceInput[beginning];
//Set a variable equal to the first
//word in the original user input
sentenceInput[beginning] = sentenceInput[end];
//Set the first letter of a word equal to
//the last letter of a word
sentenceInput[end] = reverse_words;
//Set the result equal to the variable
//sentenceInput is now the user input where each
//word is reversed
}
}
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}
When I try to run the code, the output becomes something like this:
Please enter a sentence!
Hi There
Please enter another sentence!
To Be
The first sentence reversed: erehT iH
The second sentence where each word is reversed: oT eB
The first sentence where each word is reversed: There Hi
The second sentence reversed: Be To
I tried fixing it, but to no avail. The output is never correct.
Is there some way to fix this issue? Or better yet, to simplify the code? I believe the issue is with the code in the function.
The main problem with your code is that it's using the same buffer for both transformations. In other words: you are reversing the words in the same string which you've already reversed entirely. So you need to have another copy of the original string to do these independently.
Regarding simplifying your code you need to define a function that would reverse a string given a pointer and size or begin and end pointers. Then you can use this function on your entire string or on every word you find while searching for a space character:
char *begin = sentenceInput; //points to the beginning of the word
char *end = sentenceInput + strlen(sentenceInput);
for (char *it = begin; it != end; ++it)
if (*it == ' ') {
reverse(begin, it);
begin = it + 1;
}
reverse(begin, end); //reverse the last word
The reverse function can be either std::reverse, which can be used in the above code and on the entire string as follows:
std::reverse(sentenceInput, sentenceInput + strlen(sentenceInput))
or you can create a similar function like this:
void reverse(char *begin, char *end)
{
--end; //point to the last character instead of one-past-last
while (begin < end)
std::swap(*begin++, *end--);
}
I would suggest using stack for it, it is a natural way of looking at it.
so
#include <stack>
and then the function would be like that
void cStringType::reverse_words()
{
int beginning, end, j = 0;
char reverse_words;
stack<char> lastWord;
//Reverse each word separately using loop
for (int i = 0; i <= strlen(sentenceInput); i++)
//Get the length of the sentence in the class
{
if (sentenceInput[i] == ' ' || sentenceInput[i] == '\0')
//Check for spaces or null characters
//This allows only the letters of each word to be
//reversed, not the entire sentence
{
//we want to print the last word that was parsed
while(!lastWord.empty())
{
//we print in the reverse order the word by taking off the stack char by char
cout<< lastWord.top();
lastWord.pop();
}
cout<<" ";
}
//if the letter is not space or end of string then push it on the stack
else
lastWord.push(sentenceInput[i]);
j = i + 1;
}
cout << sentenceInput << endl;
//Output of the new sentence
}

I need to return number of words in c sting after taking user input

I need to make a program that takes input from the user and then return the number of words entered to the string. I store user input in array char words[256]; I have a function called countWords. It loops though the array and if it encounters a space he counter is increased. if(words[i] == '\0') if the null character is reached the counter is stopped. It then return nSpaces + 1 to account for the first word.
But my output seems to produce the number of characters in the string instead. How can this be fixed.
#include <iostream>
#include <cstdlib>
using namespace std;
//Function Prototype
int countWords(char words[]);
int main(){
char words[256];
cout << "Enter a sentence: ";
cin.getline(words, 256);
int word_num = countWords(words);
cout << "The number of words in a string is: " << word_num << endl;
system("PAUSE");
return 0;
}
int countWords(char words[]){
int nSpaces = 0;
//unsigned int i = 0;
/*while(isspace(words[i])){
i++;
}*/
for (int i=0; i<256; i++){
if(isspace(words[i])){
nSpaces++;
// Skip over duplicate spaces & if a NULL character is found, we're at the end of the string
//while(isspace(words[i++]))
if(words[i] == '\0')
nSpaces--;
}
}
// The number of words = the number of spaces + 1
return nSpaces + 1;
}
The Output is:
Enter a sentence: Yury Stanev
The number of words in a string is: 7
You're not stopping the loop when you get to the null character. You're only testing for the null character inside the if(isspace(words[i])) block, but if the character is a space then it can't also be the null terminator. As a result, you're reading past the end of the input, and counting the spaces in the uninitialized part of the string.
int countWords(char words[]){
int nSpaces = 0;
for (int i=0; i<256 && words[i] != '\0'; i++){
if(isspace(words[i])){
nSpaces++;
}
}
// The number of words = the number of spaces + 1
return nSpaces + 1;
}
isspace counts new lines (\n), tabs (\t), \v, \f and \r.
Probably you want only white-spaces? Check for " " and "\t" only.

using strings in C++ // how do i?

I need help changing my current program so that it displays the letters already entered by the user, and displays the letters again immediately before prompting the user to enter another letter. what I have so far is below.
int main()
{
char another = 'Y';
string message = "";
while (toupper(another) == 'Y')
{
cout << "Enter a message: ";
getline(cin, message);
for (int x = 0; x < message.length(); x += 1)
cout << message.substr(x) << endl;
cout << endl << "Another message (Y/N)? ";
cin >> another;
cin.ignore(100, '\n');
}
system("pause");
return 0;
}
If you want all the characters (you entered at any time) printed, you can do the following:
Start off with two empty strings. One is a buffer, that stores the string that's currently added and the other holds all of the strings already added, like so:
string buf = "";
string messages = "";
Read your characters into your buffer, via:
getline(cin, buf);
Append the string to the other messages, already entered:
messages.append(buf);
Append a string delimiter to your messages, so you know which sequence of characters (including whitespaces) belong to the message you entered:
messages.append(";");
(BTW: Using "-quotes here is really important, to let the compiler know you are comparing strings, not characters, as there is no string::append(char s)-method defined, only string::append(string s).)
Iterate through your messages-string, and check if the character at position x is equal to ';' (Using '-quotes here is also important, because string::operator[] return a character not a string!!!). For instance you might code:
for (int x = 0; x < messages.length(); x++) {
//Test if string delimiter is reached, if so, jump to next line.
if(messages[x] == ';') {
std::cout << "\n";
}
//Else just print the string:
else {
std::cout << messages[x];
}
}
Test if another message should be entered.
OR you create a linked list of strings. Adding new strings to the list, every time you enter a new string. This might be the more elegant way to do this, however it is slightly more involved. (I'm assuming you're fairly new to programming, if not I apologize!). Check Wikipedia or cplusplus.com for more info on linked lists!
Hope I could answer your question,
lindebear

How to convert the char to string and print out from a string to main function

I am a beginner!
I had to write a code which is similar to caesar cipher, I had a main.cpp which is written below and i wrote my code in a separate ConvertString.cpp also written below.
I am having trouble printing my output from the ConvertString.cpp with the
main.cpp. Can anyone please point out my mistake. Appreciate your help a lot!
The following is the main.cpp:
#include <iostream>
#include <string>
using namespace std;
string ConvertString (string, int);
int main () {
// define the modification intger variable and
//the new modification variable to recover the text
int mod_int, recover_int;
// declare the input string , mod_string, recovered string
string input_string, mod_string, recovered_string;
// top level loop to perform modification
while (1) {
cout << "Please enter modification key (or -1 to exit)" << endl;
// read in the mod_int from user
cin >> mod_int;
// if the user is done (mod_int == -1), then exit
if (mod_int == -1) break;
// read in the text to be modified
cout << "Please enter text to be modified" << endl;
cin >> input_string;
// modify the input text
mod_string = [ConvertString(input_string, mod_int)][1];
// print out the modified text
cout << endl << "The modified text is " << endl << mod_string << endl;
// calculate a new recover_int value to recover original text
// from the modified text -- used for testing only
recover_int = 26 - (mod_int%26);
// recover original text by calling ModifyString with new recover_int value
recovered_string = ConvertString(mod_string, recover_int);
// print out the recovered text -- should match original
cout << endl << "The recovered text is " << endl << recovered_string << endl << endl;
} // end while loop
} // end main function
enter code here
The following is the ConvertString.cpp
string ConvertString (string input_string, int mod_int)
{
// your programming code
int x; //integer x is declared
x= input_string.length();
for(int index=0; index < x ; index++)
{
if(isalpha(input_string[index])) //checks the string for alphabet
{
int start = 65; //if alphabets is present in the string, it is assumed as upper case characters
//starting point is taken as character 'A' with ASCII value of 65
if(islower(input_string[index])) //if lower case character is present in string
start=97; //start is taken as 'a' with ASCII value of 97
ConvertString(input_string, mod_int)=(((int)input_string[index]- start + mod_int)% 26) + start;
//input_string is converted to integer and then modified by the formula
//formula for characters in the string to cycle in the range from a-z and A-Z.
} //closing parenthesis for if
else
cout <<input_string[index]; // if character is not a-z or A-Z, print it without any modification
} //closing parenthesis belong to - for
return input_string; // return the converted string
} //end ConvertString
You forgot a return. Change:
ConvertString(input_string, mod_int)=(((int)input_string[index]- start + mod_int)% 26) + start;
to
return ConvertString(input_string, mod_int)=(((int)input_string[index]- start + mod_int)% 26) + start;
// ^^^ Missing