I am in the process of getting password as input.
I have gone through various examples but they either used while loop or SETCONSOLE method. Both had issues.
Implementing while loop printed 1 * before I even entered a char. The other method used echo to HIDE the characters while I typed whereas I want to be printed. I would appreciate helping me masking my input with a * using SETCONSOLE method. I would be greatly obliged. The code's attached !
void signup(){
gotoxy(10, 10);
string n, p1,p2;
cout << "Enter your username: " << endl; // TEST if username already exists
gotoxy(31, 10);
cin >> n;
lp:
gotoxy(10, 11);
cout << "Enter your password: " << endl; // TEST if username already exists
gotoxy(31, 11);
getline(cin, p1);
system("cls");
gotoxy(10, 10);
cout << "Re-Enter your password to confirm: " << endl; // TEST if username already exists
gotoxy(45, 10);
getline(cin, p2);
if (p2!=p1)
{
system("cls");
gotoxy(10, 10);
cout << "Passwords donot match! Please enter again!";
goto lp;
}
}
Here a simple example using getch. YES it c method, not c++, but it is very efficient.
It can be extended to block spaces, tabs, etc.
Also see the comments in the code...
#include <iostream>
#include <string>
#include<conio.h>
using namespace std;
int main(){
string res;
char c;
cout<<"enter password:";
do{
c = getch();
switch(c){
case 0://special keys. like: arrows, f1-12 etc.
getch();//just ignore also the next character.
break;
case 13://enter
cout<<endl;
break;
case 8://backspace
if(res.length()>0){
res.erase(res.end()-1); //remove last character from string
cout<<c<<' '<<c;//go back, write space over the character and back again.
}
break;
default://regular ascii
res += c;//add to string
cout<<'*';//print `*`
break;
}
}while(c!=13);
//print result:
cout<<res<<endl;
return 0;
}
You probably want to use getch() (#include <conio.h>) to read a character without its being echoed to the screen. Then when you've validated that it's a character you want to accept, you can print out a * at the correct position.
Related
The purpose of this program is to check if the character entered by the user is alphanumeric. Once the void function confirms correct entry then it is passed to string test to output a message. I know it's not great coding but it has to be done this way.
I keep getting a logic error & I can't figure out why? Can someone please help?
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void get_option(char& input);
/**
Takes character entered user input and loops until correct answer
#param y character entered by user
#return to main() once valid entry received
*/
string test(char);
/**
Takes checks character entered user input and loops until correct answer
#param y alphanumeric character entered by user
#return to main() once valid entry received
*/
int main()
{
char y;
//call get_option to prompt for input
get_option(y);
//call test after user input is valid
test(y);
return 0;
}
void get_option(char &x)
{
cout << "Please enter an alphanumeric character: ";
cin >> x;
while (!(isdigit(x)||islower(x)||isupper(x)))
{
cout << "Please enter an alphanumeric character: ";
cin >> x;
}
}
string test(char y)
{
if (isupper(y))
{
cout << "An upper case letter is entered!";
} else if (islower(y)) {
cout << "A lower case letter is entered!";
} else if (isdigit(y)) {
cout << "A digit is entered!";
}
return "";
}
I got the program to work perfectly by changing the return type of the test(char) function:
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
void get_option(char& input);
/**
Takes character entered user input and loops until correct answer
#param y character entered by user
#return to main() once valid entry received
*/
int test(char); //Changed from string to int
/**
Takes checks character entered user input and loops until correct answer
#param y alphanumeric character entered by user
#return to main() once valid entry received
*/
int main()
{
char y;
//call get_option to prompt for input
get_option(y);
//call test after user input is valid
test(y);
return 0;
}
void get_option(char &x)
{
cout << "Please enter an alphanumeric character: ";
cin >> x;
while (!(isdigit(x)||islower(x)||isupper(x)))
{
cout << "Please enter an alphanumeric character: ";
cin >> x;
}
}
int test(char y) //Also changed from string to int
{
if (isupper(y))
{
cout << "An upper case letter is entered!";
} else if (islower(y)) {
cout << "A lower case letter is entered!";
} else if (isdigit(y)) {
cout << "A digit is entered!";
}
return 0;
}
(Testing was on JDoodle using the C++14 compiler.)
(Also, tested using Xcode. Still works)
When I tried it in my setup (g++ 6.4, cygwin), I did not get any output. When I added << endl to the output lines, the output showed up.
I suspect you're experiencing the same problem.
string test(char y)
{
if (isupper(y))
{
cout << "An upper case letter is entered!" << endl; // Add endl
}
else if (islower(y))
{
cout << "A lower case letter is entered!" << endl;
}
else if (isdigit(y))
{
cout << "A digit is entered!" << endl;
}
// This does not make sense but it is syntactically valid.
return 0;
}
JiveDadson is right. The problem was the return 0 line. It causes undefined behavior. Changing the that line to
return "";
fixes the output problem, endl or not. Having the endl is nicer but is not necessary. Fixing the return statement is the most important task.
In this rather simple exercise I have to receive an user input, store said input into a string, pass the string to a function by reference and finally modify the string so that every character is "parsed" by the toupper() function.
However, should the user insert 'q' as input, the program stops saying "Bye" OR if he just presses the Enter Key, the program is supposed to say something like "Hey, this string is empty".
Now the real problem here is in the last part since my code won't manage the case where the user inputs only the Enter Key value (to be honest, even if I just text a bunch of spaces followed by the Enter Key, nothing happens)
void uppercase(std::string &);
int main(){
using namespace std;
string ex2;
cout << "Exercise 2" <<endl;
while(ex2!="Bye"){
cout << "Enter a string(q to quit): ";
cin >> ex2;
cout << "Was: " << ex2 << endl << "Now is: ";
uppercase(ex2);
}
return 0;
}
void uppercase(std::string &str){
using namespace std;
if(str[0]=='\n')
cout <<"Empty string dude!" << endl;
else{
if(str.length()==1 && str[0]=='q'){ //press 'q' to exit program
str="Bye";
cout << str;
}
else{ //uppercase
for(int i=0;i<str.length();i++){
str[i]=(toupper(str[i]));
}
cout << str <<endl;
}
}
}
I also tried the compare() function and even to compare the whole string to null (pointless, but still worth a shot) and to the string "";
Sorry for the bad interpretation of your problem, trying
if( (str.length()==1 && str[0]=='q') || str.length() == 0)
{}
May help you out of the problem
#include <iostream>
#include <string.h>
#include <string>
#include <fstream>
using namespace std;
int get_ascii_int(char ch);
int get_offset_ascii(char ch2, int offset);
//int print_string_ints(string test_string);
int method3_substitution_abc();
//above are the function declarations
int main()
{
string test_string;//input of string
char ch = 0;//used in method1
char ch2 = 0;//used in method2
int index1 = 0;//used in for loop method1
int index2 = 0;//used in for loop method2
int offset = 0;//input of how much to offset
int new_ascii = 0;//the new ascii with offset
int ascii_value1 = 0;//the ascii value of the char
int option;//the menu choice of encryption method
int decision;//the decision to save or display
ofstream method1;//method 1 text file
ofstream method2;//method 2 text file
ofstream method3;//method 3 text file
string test_string_copy;//copy of string method 2
//Below is a description of the methods of encryption
cout << "There are three methods of encryption, listed below, to choose from: " << endl;
cout << "1. Converting characters into the corresponding ASCII values. " << endl;
cout << "2. Shifting characters right/left using the ASCII value of the characters ";
cout << "and a set offset amount. " << endl;
cout << "3. Using a reverse alphabet, so each letter will be replaced with the letter ";
cout << "on the opposite end of the alphabet. For example, A would become Z. " << endl;
cout << "Which encryption method would you like to use, 1, 2, 3? ";
cin >> option;
switch (option)
{
case '1':
method1.open("method1.txt");
cout << "Input a word or name: ";
getline(cin, test_string);
for (; index1 < test_string.size(); index1++);
{
ascii_value1 = get_ascii_int(test_string[index1]);
}
cout << "Would you like to display the file or save it, enter 1 for display or 2 for save?";
cin >> decision;
if (decision == '1')
{
cout << "The encrypted code is " << ascii_value1 << endl;
}
else
{
if (method1.is_open())
{
method1 << "The encrpyted code is " << ascii_value1 << endl;
method1.close();
}
else
cout << "Unable to open file." << endl;
}
break;
case '2':
method2.open("method2.txt");
cout << "Input a word or name: ";
getline(cin, test_string);
test_string_copy = test_string;
for (; index2 < test_string_copy.size(); index2++);
{
new_ascii = get_offset_ascii(test_string_copy[index2], ch2);
}
cout << "Would you like to display the file or save it, enter 1 for display or 2 for save?";
cin >> decision;
if (decision == '1')
{
cout << "The encrypted code is " << new_ascii << endl;
}
else
{
if (method2.is_open())
{
method2 << "The encrypted code is " << new_ascii << endl;
method2.close();
}
else
cout << "Unable to open file." << endl;
}
break;
case '3':
method3.open("method3.txt");
method3_substitution_abc();
break;
}
return 0;
}
//listed below are the function definitions
int get_ascii_int(char ch)
{
return ((int)ch);
}
int get_offset_ascii(char ch2, int offset)
{
int new_offset_value;//the value after adding the determined offset to the ascii value of the letter
new_offset_value = (int)ch2 + offset;
(char)new_offset_value;
return (new_offset_value);
}
//int print_string_ints(string test_string)
//{
//for (int i = 0; i < test_string.size(); i++)
//{
//(int)test_string[i++];
//}
//return 0;
//}
int method3_substitution_abc()
{
char test_string[100];
cout << "Enter a name or phrase: ";
cin >> test_string;
if (isupper((int)test_string))
{
int stalpha = 65;//start of alphabet
int endalpha = 90;//end of alphabet
char b[100];//array to reverse the alphabet
for (int i = 0; test_string[i] != '\0'; i++)
{
b[i] = endalpha - (test_string[i] - 65);
}
}
else if (islower((int)test_string))
int stalpha = 97;//start of alphabet
int endalpha = 122;//end of alphabet
char b[100];//array to reverse the alphabet
for (int i = 0; test_string[i] != '\0'; i++)
{
b[i] = endalpha - (test_string[i] - 97);
}
return 0;
}
I am trying to write this encryption program. And I am just getting really confused on why it won't run.
For example the switch statement is not running correctly, it will go to the correct case and then skip the input of the string?
This is my first experience with C++ so I struggle to debug.
I am having issues with saving the file to a text file after the user chooses to save or display? It has to be done after every case in the switch statement.
I also know the for loops I am using are not correct for method 1 and 2? Could someone check those out and tell me what the issue is. I am pretty sure it has to do with the parameters for the for loop.
And I don't know if I should use a string or an array for this? (In the part where the user inputs a string
At least the first problem you've identified (with the switch statement) is pretty simple and clear.
You've defined option as an int, so when you read it it's read as an integer. That means if the user enters 1, it'll have the value 1, which is different from the value '1'. '1' is a character that will (for example) print as 1, but its value is actually 49 in most character sets.
You have two obvious choices: either change option to be a char, so it'll be read as a character instead of an integer, or else change the values in the switch statement from '1', '2', etc., to just 1, 2, etc.
At a guess, the problem you're seeing from getline is a fairly common one when you mix a string extractor (e.g., cin >> my_string;) with std::getline. The string extractor extracts a string from the stream, but leaves the new-line character in the stream buffer. Then when you call std::getline, it reads that new-line as an empty string, so it doesn't wait for you to enter more input.
If you really have to mix the two this way, you probably want to add a call to std::cin.ignore to read and ignore any data up to and including the new-line character. Then when you call std::getline, it'll actually read some data.
I am creating a program that allows users to key in their user name and password. the problem is, when the system prompts to "Enter userName:" and I hit enter key, it will print out "Name cannot contain a blank"
but if I hit a FEW spaceBars and hit enter key and make it blank field after that ,it skips to prompt the user to enter the password without printing out "Name cannot contain a blank" and prompting the user to enter the userName again.
how should I change my codes to ensure that it will still prompt the user to enter the userName again even though I hit a spacebars and hit enter? please advise. thanks
code
string userName=" ";
string password;
cout << "Enter UserName:";
while (getline(cin, userName)) {
if (userName.empty()) {
cout << "Name cannot contain a blank."<< endl;
cout << "Enter userName:";
userName = userName;
//throw errorMsg;
}
if(!userName.empty()) {
cout << "Enter Password";
}
}
Username validation is not trivial, for many reasons. You don't want to be in the business of manufacturing what you "think" the user wanted to type, while at the same time it is clear you want to avoid a potentially long validation of what is going to be invalid.
In the end, I would suspect you can simply take the prospect entry, strip all the whitespace, and if there is anything left over, submit the original entry for validation. Don't bite off the business of validating something the user may have meant to type. I.e.
"\t\t "
should be grounds for a re-prompt, while
"John Smith"
"\t WillJohnson "
"Gary"
should all be submitted verbatim, and let the chips fall where they may.
That said,
bool isValidUserName(std::string name)
{
name.erase(std::remove_if(name.begin(), name.end(),
[](char c){ return std::isspace(static_cast<unsigned char>(c));}), name.end());
return !name.empty();
}
should do that for you. A sample is below:
int main()
{
std::cout << std::boolalpha << isValidUserName("\t \t ") << std::endl;
std::cout << std::boolalpha << isValidUserName("\t Will Johnson ") << std::endl;
return 0;
}
Output
false
true
Assuming a C++11 compliant compiler your test for spaces could be using std::find_if
if (std::find_if(userName.begin(), userName.end(), isspace))
!= userName.end())
or
if (std::find_if(userName.begin(), userName.end(),
[=](char c){return isspace(c);}) != userName.end())
Notice that several characters are space-like ' ' but also '\t' (tabulation) etc...
just consider the space as a character and increment it when you find it
The logic is to check if the starting character of the username is a blank space and also the last slot of the string is not a blank space.
example :
This should be accepted = "a b".
But
this should not be " a ".
or this should not be " a".
or this should not be "a ".
if (userName[0]!=" " && userName[userName.size()]!=" "){
//accept this case and move on.
}
else{
//reject all other cases.
}
#include <iostream>
#include <vector>
using namespace std;
int main(){
string username, password;
int un = 1;
int ps = 1;
while(un){
cout<<"Username:";
getline(cin,username);
int usize = username.size();
vector <string> v ;
v.insert(v.begin(), username);
if (usize==1){
if(username==" "){
cout<<"Username can not be blank"<<endl;
}
else{
un=0;
}
}
else{
int check=0; int trim = 0;
for (int i=0; i<usize; i++){
if (username[i]!=' '){
check=1;
trim = i;
break;
}
}
if(check==1){
un=0;
}
else{
}
}
}
while(ps){
cout<<"Password:";
getline(cin,password);
int usize = password.size();
vector <string> v ;
v.insert(v.begin(), password);
if (usize==1){
if(password==" "){
cout<<"Password can not be blank"<<endl;
}
else{
ps=0;
}
}
else{
int check=0;
for (int i=0; i<usize; i++){
if (password[i]!=' '){
check=1;
break;
}
}
if(check==1){
ps=0;
}
else{
}
}
}
cout<<endl;
cout<<"----------------------------------------------"<<endl;
cout<<"Username is: "<<username<<endl;
cout<<"Password is: "<<password<<endl;
return 0;
}
Check if the string is empty if so then do the empty validation
If the string is not empty then check if it has spaces i.e find_first_not_of("\t ") if this returns number greater than 0 we know the username has leading white/tab spaces followed by zero or more characters. i.e leading spaces then the username
Its upto you to now do the validation for a good username.
#include <iostream>
#include <cstring>
using namespace std;
int main() {
string userName = " ";
string password;
cout << "Enter UserName:";
while(getline(cin, userName)) {
if(userName.empty()) {
cout << "Empty String";
} else if(userName.find_first_not_of("\t ") > 0) {
cout << "Could contain spaces followed by username or just spaces";
} else {
cout << "User Name is Valid";
}
}
return 0;
}
I coded an easy game. I know how to use cout/cin but having problems with printf/scanf. The code below works well with cout/cin. Question is, how to convert them into printf/scanf? Why the codes in comment don't work?
Edit: I mean if I delete cout/cin lines and when I use printf/scanf instead it doesn't work properly.
#include <iostream>
#include <time.h>
using namespace std;
int main()
{
srand(time(NULL));
int min=0, max=1000, guess, counter=0;
bool winner=false;
char answer;
while(counter<10){
guess = rand()%(max-min)+min;
// printf("Did you pick %d? \t", guess);
// scanf("%c", &answer);
cout << "Did you pick " << guess << "?\t";
cin >> answer;
if(answer=='y'){ // yes
winner=true;
// printf("Computer wins.\n");
// printf("You picked: %d", guess);
cout << "Computer wins." << endl;
cout << "You picked: " << guess;
break;
}
else if(answer=='m'){ // more
min=guess;
counter++;
}
else if(answer=='l'){ // less
max=guess;
counter++;
}
}
if(winner==false){
// printf("User wins.\n");
cout << "User wins." << endl;
}
return 0;
}
The problem is that scanf() doesn't remove the newline '\n' character from stdin, so on the next iteration the next scanf() reads it and tries to process it, seeming to ignore the input.
Try this instead:
scanf("\n%c", &answer);
That way, you expect the newline and scanf() consumes it.