I'm currently making a login form for my project, but I can't move on on this one. I want my program to delete a character(in password) when I'm pressing the backspace button, but the program is not reading it.
Here's my code
string username, password, power;
char ast=' ';
int aste = 0, accessLevel;
ofstream addAcc;
addAcc.open("Accounts.txt");
cout<<"Username: ";cin.ignore();getline(cin, username);
cout<<"Password: ";
do
{
ast = getch();
if (ast == 13 || ast == ' ' )
{
break;
}
if(ast==8 || password!="")
{
cout<<"\b \b";
password.erase(password.size()-1);
}
cout<<"*";
password+=ast;
aste ++;
}while(ast!=13 || ast!=' ');
do
{
cout<<"Enter Access Level(0-1): ";cin>>accessLevel;
switch(accessLevel)
{
case 0:
{
power = "Cashier";
break;
}
case 1:
{
power = "Manager";
break;
}
default:
cout<<"Invalid access level."<<endl;
}
}while(accessLevel>1||accessLevel<0);
Thank you for those who will help.
On some platforms getch() will return the DEL character (ascii 127) when you hit BACKSPACE. So change your line
if(ast==8 || password!="")
to
if((ast==8 || ast==127) && !password.empty())
You probably don't want to erase a character everytime that password is not an empty string either, so I removed || password!="" from the condition too. Instead you want to erase one character only if the password is not empty. So you need an && instead of an ||.
Also note, that you're adding the character returned by getch() unconditionally. So if the user enters BACKSPACE, you erase the last character, but append BACKSPACE to the password. So you should only append the character returned by getch() if it was not a BACKSPACE (or DEL).
Thus your code might look like this:
if((ast==8 || ast==127) && !password.empty())
{
cout<<"\b \b";
password.erase(password.size()-1);
aste--;
}
else
{
password+=ast;
cout<<"*";
aste++;
}
do
{
c = _getch();
if (c == 13 || c == ' ') // checking ascii key 13 pressed or no
{
break;
}
if (c == 8 || c == 127)
{
if (Password.size() != 0){
cout << "\b \b";
Password.erase(Password.size() - 1);
StarNum--;
}
}
else {
Password += c;
cout << "*";
StarNum++;
}
} while (c != 13 || c != ' ');
Use
#include <conio.h>
and
ch = _getch();
instead ch = getch();
and also change the condition like this
if(ch == 8)
{
password.erase(password.size()-1);
aste--;
}else
{
password +=ch;
aste++;
}
Related
What it's supposed to do
My piglatin program is supposed to take a phrase from user input and output it into pig latin. Basically it would turn a word such as "hello" into "ellohay".
My problem
When I input hello my man the output is ellohay y man an may and when I just input hello my the output is ellohay y may. As you can see, after it translates the first word successfully, it struggles on the second word. It places a space after the y and mayI cannot figure out for the life of me why this keeps happening. The output is even stranger when I input more than two words, as shown above. What I want to happen is for it to output ellohay ymay anmay when I input hello my man. Code is below. Thanks!
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
void phrase_Parser(string); // Goes through phrase and looks for ' ' to then pass to pigLatin_Translator()
void pigLatin_Translator(string);
int main()
{
string phrase; //used for user word or phrase to be translated to piglatin
cout << "Enter any word: ";
getline(cin, phrase);
phrase_Parser(phrase);
return 0;
}
void phrase_Parser(string phrase) {
int startCount = 0;
for (int i = 0; i < phrase.length(); i++) {
if (phrase[i] == ' ') {
string word = phrase.substr(startCount, i);
startCount = (i + 1); // decides where to start the word next time it is ran through
pigLatin_Translator(word); // runs word through translator
}
}
}
void pigLatin_Translator(string word) {
string partOne;
string partTwo;
for (int x = 0; x < word.length(); x++) {
if (word[0] == 'q' && word[1] == 'u') {
cout << word.substr(2, word.length()) << word.substr(0, 2) << "ay ";
break;
}
else if ((word[x] == 'a') || (word[x] == 'e') || (word[x] == 'i') || (word[x] == 'o') || (word[x] == 'u') || (word[x] == 'y')) {
partOne = word.substr(x, word.length()); //from first vowel to end of word
partTwo = word.substr(0, x); // from first letter to first vowel, not including the vowel
cout << partOne << partTwo << "ay "; // adding "ay" to the end of the word
break;
}
}
}
Your problem is in the line string word = phrase.substr(startCount, i);
You are using substr incorrectly. The second argument to substr is the length of the substring you wish to extract. Replace i with i-startCount and you should be good to go.
Alternatively, search for a nicer way to split strings. There are a number of options that are much easier than doing it manually.
Following is the code for a login program that inputs the username, and then the password, while echoing '*' for every character entered, and then compares the username and password to preset values to see if they match and exits the program if it is true, else it goes back to the beginning.
int main()
{
int i = 0; string u; char parr[i + 1], ch;
while (1)
{
system("cls");
cout << "Enter username." << endl;
cin >> u;
system("cls");
cout << "Enter password." << endl;
i = 0;
while (1)
{
tag:ch = getch();
if (ch == '\r')
{
break;
}
if (ch == '\b')
{
cout << '\b';
--i;
ch = '\0';
parr[i] = '\0';
cout << ' ' << '\b';
goto tag;
}
parr[i] = ch;
ch = '*';
cout << ch;
++i;
}
parr[i] = '\0';
string p = "password";
if (u == "username" && parr == p)
{
system("cls");
cout << "Welcome!";
break;
}
else
{
system("cls");
cout << "Username and password entered does not match! Please try again.";
}
getch();
}
getch();
}
Now, here's the problem: Recently, I found out that this method of input (for the password) doesn't work as intended with Backspace, Delete, or the arrow keys. All of these keys input certain symbols instead of deleting characters or moving the cursor. So I tried out a workaround (currently only) for the backspace key. All worked fine- the previous character was deleted when I pressed backspace, but in the end, after the comparison with the preset values, it showed that the password doesn't match.
If you could please help me in the following:
*Working backspace functionality (and delete and arrow keys if possible)
*Pressing Esc at ANY point of the program quits it.
*I have used goto in this program, whose atrocities we all already know of. Please suggest me a way to avoid this, and also to make all this code neater than its current messy state.
Use continue instead of goto. In your case this will do the same: jump to the start of the loop.
Then run a debugger and watch what happens with your array if you input backspaces.
I'm working on a project from class and it's a text analysis project. We're supposed to load a document into the program and basically read data from it. Ex: (word count, sentence count, etc.). For some reason, my first function isn't working correctly: my loadDocument function is supposed to load the document into the program.
Here is the code in main to call that function:
case 1: // Load Document
{
string inputLoc;
cout << "Please input the document name:" << endl;
cin >> docName;
myDocs[docCount].setName(docName);
myDocs[docCount].id = docCount;
cout << "Input Location: " << endl;
cin >> inputLoc;
myDocs[docCount].loadDocument(inputLoc);
docCount++;
break;
}
I have docName initialized outside of the case - before it.
Here is my loadDocument in side my Document class:
void Document::loadDocument(string name)
{
ifstream myFile(name);
int numOflines = 0;
string theLine;
char words;
while (myFile.get(words))
{
switch (words)
{
case '.':
numOflines++;
break;
case '?':
numOflines++;
break;
case '!':
numOflines++;
break;
}
}
lineCount = numOflines;
setLineCt(numOflines);
arr = new Line[lineCount];
myFile.close();
char theChar;
ifstream myFile2(name);
int key = 0;
if (myFile2.is_open())
{
for (id = 0; id < lineCount; id++)
{
while (theChar != '.' || theChar != '!' || theChar != '?')
{
myFile2 >> noskipws >> theChar;
theLine[key] = theChar;
key++;
}
myFile2 >> theChar;
arr[id].setStr(theLine);
}
}
}
I just wanted to know if my loadDocument has any evident bugs? For some reason, it's not actually loading a document into the program. For the input location, I typed in the exact file location of a text file that I want to input. For ex: C:\Users\Documents------. After I input that, my program just goes into an infinite loop.
Is my loadDocument doing what it's supposed to do? It's supposed to open a document and extract the number of sentences from it as well as number of words.
Also, am I testing it correctly by typing in that file location like that? I'm new to file input/output sorry.
Your while() loop is incorrect:
while (theChar != '.' || theChar != '!' || theChar != '?')
|| is not the right conditional operator here. If one condition is false, the two others will be true, thus leading to the infinite loop. You have to use &&:
while (theChar != '.' && theChar != '!' && theChar != '?')
I am running into an error during my program's runtime:
"Debug Assertion Failed! ... Expression: string subscript out of range."
This is happening in my for loop when my if statement attempts to check if the character at 'i' in the string isDelimiter() or isOperator(). I am passing the char 'check' as an attribute, and in the comments I have made sure that 'check' is grabbing the correct character. I've been working on this issue for a while and I can't seem to resolve it.
EDITED AT BOTTOM
string inputLine = "";
string inputString = "";
int main()
{
ifstream input("input.txt");
getline(input, inputLine);
if (input.is_open())
{
while (!input.eof())
{
getline(input, inputLine);
for (int i = 0; i<inputLine.length(); i++)
{
char check = inputLine[i];
//cout << check << "\n"; // test for correct character
if ((inputLine[i] != ' ') || (inputLine[i] != isDelimiter(check)) || (inputLine[i] != isOperator(check)))
{
inputString = inputString + inputLine[i];
//cout << lexer(inputString) << "\n";
//cout << inputString;
} // end if
else
{
cout << lexer(inputString);
if (inputLine[i] == isDelimiter(i))
cout << inputLine[i] + "\tDELIMITER";
if (inputLine[i] == isOperator(i))
cout << inputLine[i] + "\tOPERATOR";
inputString = "";
} // end else
//cout << inputString << "\n";
} // end for
} // end while
//input.close();
}
else cout << "Unable to open file.";
return 0;
}
Here are the isDelimiter() and isOperator() methods.
bool isOperator(char c)
{
if ((inputLine[c] == '+') || (inputLine[c] == '-') || (inputLine[c] == '*') || (inputLine[c] == '/') || (inputLine[c] == '=') || (inputLine[c] == '%') || (inputLine[c] == '<') || (inputLine[c] == '>'))
return true;
else
return false;
}
bool isDelimiter(char c)
{
if ((inputLine[c] == ';') || (inputLine[c] == '(') || (inputLine[c] == ')') || (inputLine[c] == ','))
return true;
else
return false;
}
Any help is appreciated!
EDIT::
After reviewing my code some more I realized the mistake, but I still have another. That runtime error was because in my isOperator() and isDelimiter() functions, I was checking inputString[c] rather than just 'c'. Silly mistake, I know. However, although there is no longer an error, the program still skips checking the isOperator() and isDelimiter() methods, and only goes into the else statement when it reads a ' '. Why isn't it going into my else statement for operators and delimiters?
Your functions take char, change them to int:
bool isDelimiter(char c) //should be int
{
if ((inputLine[c] == ';') || (inputLine[c] == '(') || (inputLine[c] == ')') || (inputLine[c] == ','))
return true;
else
return false;
}
I figured it out, and even though they're simple mistakes, maybe it'll help somebody in the future. After all, I was stumped for a while.
They were mainly just syntax errors, I really needed to freshen up on my coding.
This is the format my functions now follow. Notice I'm finally passing the correct values.
bool isDelimiter(char c)
{
if ((c == ';') || (c == '(') || (c == ')') || (c == ','))
return true;
else
return false;
}
And this is how I am now calling them. I was trying to check if the input itself was equal to the function, which would be like asking if "helloworld" == TRUE. Obviously that wasn't working, and I wanted to kick myself once I figured that out. Here's the snippet:
if ((inputLine[i] == ' ') || (isDelimiter(check)) || (isOperator(check)))
{
cout << lexer(inputString);
if (isDelimiter(check))
{
cout << inputLine[i] << "\t\tDELIMITER\n";
}
if (isOperator(check))
{
cout << inputLine[i] << "\t\tOPERATOR\n";
}
inputString = "";
} // end if
else
{
inputString = inputString + inputLine[i];
} // end else
That has resolved my basic issues, now onto bigger ones.
i'm writing a code to receive password input. Below is my code... the program run well but the problem is other keys beside than numerical and alphabet characters also being read, for example delete, insert, and etc. can i know how can i avoid it? tq...
string pw="";
char c=' ';
while(c != 13) //Loop until 'Enter' is pressed
{
c = _getch();
if(c==13)
break;
if(c==8)
{
if(pw.size()!=0) //delete only if there is input
{
cout<<"\b \b";
pw.erase(pw.size()-1);
}
}
if((c>47&&c<58)||(c>64&&c<91)||(c>96&&c<123)) //ASCii code for integer and alphabet
{
pw += c;
cout << "*";
}
}
Filter using isalnum() for alpha-numeric or isalpha() for only alphabets.
Also, you are checking c == 13 twice, following will suffice.
while(1){
//
if(c == 13)
break;
//
}
if( isalnum(c) ){
// 'c' is acceptable
}
Some assertion is failing during execution which throws that error.
If you have access to it, you are much better off using the GNU getpass function.