getline() gets bypassed without proper user input the first time [duplicate] - c++

This question already has answers here:
getline not asking for input? [duplicate]
(3 answers)
Closed 9 years ago.
cout << "Type in your third message below:\n";
getline(cin, msgth);
if (msgth.length() > 0 && msgth.length() < 500) {}
else
{
system("cls");
cout << "Your message has to be between 1 and 500 characters long...";
goto prot;
}
So, whenever I get to this piece of code, it's like it automatically presses return, and "skips" the getline() function (AKA, goes to the prot label). The same thing happens further up for some reason. However, after a bit of experimenting, I've found out that when using this:
input:
if (special == 0)
{
cout << "Choose your input message below:\n";
getline(cin, inp);
if (inp.length() > 0 && inp.length() < 500) {}
else
{
system("cls");
cout << "Your message needs to be between 1 and 500 characters long\n";
goto input;
}
}
It does work the second time (with other words, after going to the input label). The difference between these two codes is that the first one has to bypass a std::cin code before getting back to getline(), while the other one doesn't.
A solution and some explaination would be gladly appreciated.

The following works for me:
#include <iostream>
#include <string>
int main() {
std::string str;
start:
std::cout << "prompt:\n";
std::getline(std::cin, str);
if (0 < str.length() && str.length() < 20) {}
else {
std::cout << "invalid.\n";
goto start;
}
std::cout << "input: \"" << str << "\"\n";
}
How is yours different from this?

Related

Does anyone have any idea how to make so the mask of the password is delayed by a second or two before it replace the password with '*'?

here is some fragment of my code. Can anyone help me? On how to make so the mask of the password is delayed by a second or two before it replaces the password with '*'?
struct adminInfo
{
string adminID;
string adminName;
string adminPassword;
};
void create_admin (adminInfo ad [], int &count)
{
char pass = 0;
const char BACKSPACE = 127;
const char RETURN = 10;
cout << " **************************************" << endl;
cout << " REGISTER ADMINISTRATOR" << endl;
cout << " **************************************" << endl;
cout << " Enter admin registration number (ID) : "; cin >> ws;
getline (cin, ad[count].adminID);
cout << " Enter admin full name : "; cin >> ws;
getline (cin, ad[count].adminName);
cout << " Please create your password : ";// cin >> ws;
//getline (cin, ad[count].adminPassword)
while ((pass=getch(void)) != RETURN)
{
if (pass == BACKSPACE)
{
if (ad[count].adminPassword.length() != 0)
{
cout << "\b \b";
ad[count].adminPassword.resize(ad[count].adminPassword.length() - 1);
}
}
else
{
ad[count].adminPassword += pass;
cout << "*";
}
}
count++;
}
Side note: Should std::endl always be used?
Also it might be easier for me to answer if I knew what libraries you were using. For the sake of simplicity I will presume you use the standard C++ library iostream for cout etc conio.h for getch() string for string and namespace std.
If you don't mind the last character being seen, you could literally just wait for the user input like this:
while ((pass = getch()) != RETURN) {
/* Making length variable so I don't have to call length() function multiple times and it looks cleaner */
int length = ad[count].adminPassword.length()
/* Using bigger than zero just to make it more explicit */
if (length > 0) {
/* Change last character to asterisk */
cout << "\b \b*";
}
if (pass == BACKSPACE) {
if (length > 0) {
cout << "\b \b";
ad[count].adminPassword.resize(length - 1);
}
} else {
ad[count].adminPassword += pass;
/* Instead of asterisk as that is now changed at every keypress after first input */
cout << pass;
}
}
If you wish to actually wait you could just include <windows.h> (or unix equivalent) and use Sleep(milliseconds) function like this in the else statement:
cout << pass;
ad[count].adminPassword += pass;
Sleep(Time in milliseconds)
cout << "\b \b*";
But this will wait the time in milliseconds to print out the next value and will give a pretty confusing and questionable output if you type above 3 wpm.
This is the best that I could think of, I'm not that knoweledgeable about C++ so sorry if I could not answer your question well enough.
I'm presuming you could do something with multithreading to make it wait while taking input. But as I said I do not know much about C++ so I will leave that to someone smarter than me ;D.

Why are the paired elements in my vector outputting wrong? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
For context, I am working on a reward system program for a store. I have a file which contains a list of items with the points the customer earns underneath the name of each item. Here is what the file contains:
rolling papers
1
lighter
1
silicone pipe
5
glass pipe
8
water pipe
10
I am trying to read from the file into two different variables then store those variables in a vector of pairs. But I've noticed that when I output the pairs from the vector the first letter of the item is missing, and the points are completely off. I've tried to change the point to a char instead of an int, and did the same in the paired vector. Both gave similarly inaccurate/strange outputs. What am I doing wrong here? Thanks guys. Here is the part of my program where I'm trying to store the items/points in a paired vector:
int answer;
int points;
std::string tempName;
std::string name;
std::string item;
std::ifstream inFS;
std::vector<std::string> nameList;
std::vector<std::pair<std::string, int>> pairedList;
std::cout << "Would you like to add points to a member's name? If not, input 0 to look at other options!" << std::endl;
std::cout<< "Otherwise, input 1 to continue to the point system." << std::endl;
std::cin >> answer;
if (answer == 0)
options();
if (answer == 1) {
inFS.open("items.dat");
if (inFS.is_open())
std::cout << "File opened successfully." << std::endl;
while (std::getline(inFS, item)) {
inFS >> points;
pairedList.push_back(make_pair(item, points));
}
if (!inFS.eof())
std::cout << "Not able to reach end of file" << std::endl;
inFS.close();
for (int i = 0; i < pairedList.size(); i++)
std::cout << pairedList[i].first << " " << pairedList[i].second << std::endl;
exit(1);
}
}
Try changing the inFS >> points for another std::getline(inFS, points_str) (notice you need a std::string points_str{};); then you can do a make_pair(item, std::stoi(points_str)). [Demo]
#include <iostream> // cout
#include <string> // getline, stoi
int main()
{
std::string item{};
std::string points{};
while (std::getline(std::cin, item))
{
std::getline(std::cin, points);
std::cout << "item = " << item << ", points = " << std::stoi(points) << "\n";
}
}

Input Validation Infinite Loop C++ [duplicate]

This question already has answers here:
Why would we call cin.clear() and cin.ignore() after reading input?
(4 answers)
Closed 2 years ago.
First off, I am very new to C++ (I literally started learning it 2 hours ago, so go easy on me)
This simple program is supposed to check whether or not the user input is a valid number between 0 and 101 and simply respond, valid or invalid.
#include <iostream>
int main() {
bool isValidNum = false;
do
{
std::cout << "How many samples were collected?\n";
int numOfSamples;
std::cin >> numOfSamples;
isValidNum = (numOfSamples > 0 && numOfSamples < 101);
if (isValidNum) {
std::cout << "valid\n";
}
else {
std::cout << "invalid\n";
}
} while (isValidNum == false);
}
It works. Except that if you put anything other than an integer it loops infinitely.
I may have over stretched myself by using a do/while loop whilst so unfamiliar with this language.
What is wrong with the condition flow? (I assume i'm just being incredibly smoothbrained and need some coffee)
#include <iostream>
#include <string>
using namespace std;
int main() {
bool isValidNum = false;
string input;
int numOfSamples;
std::cout << "How many samples were collected?\n";
do
{
getline(cin, input, '\n');
if (input == "")continue;
numOfSamples = atoi(input.c_str());
isValidNum = (numOfSamples > 0 && numOfSamples < 101);
if (isValidNum) {
std::cout << "valid\n";
}
else {
std::cout << "invalid\n";
}
} while (isValidNum == false);
}

how do i use argc and argv insted of cin in my code, new to command line argument and i would like to learn how i could do it [duplicate]

This question already has answers here:
Parsing Command Line Arguments in C++? [closed]
(42 answers)
Closed 2 years ago.
uni year 2 student learning c++, and i have this code i created, within this code i use cin to ask for user input but my instructor want "You need to use argc and agrv[] in your main function. So users can inputs information into your program when they run it. For instance, "yourprogram.exe -P 50"." but i dont know how i could implement it. Thank the help
int main(int argc, char* argv[])
{
if (userchouise == "P" | userchouise == "A" )
{
if (userchouise == "P") // {
cin>>uservlue;
if (uservalue >= 100 | uservalue <= 0)
{
cout << "p " << endl;// Invalid duty cycle value
return 0;
}
else
{
cout<<uservalue<<endl;
}
return 0;
}
if (userchouise == "A") // can only input values from 0-7
{
int userPort;
cout << "enter port number between 0 to 7" << endl;
cin >> userPort;
if (userPort >= 0 | userPort <= 7)
{
}
else
{
cout << "a " << endl;//Invalid ADC channel number
}
return 0;
}
}
else
{
cout << "I " << endl;
}
return(0);
}
The argc/argv is the C-way of passing command-line parameters to the program, which is still used in C++, but use std::vector<std::string> args(argv+1, argv+argc); as first statement to work with the parameters as a vector of strings or use a library which can make it more convenient to work with parameters the way it is expected and to provide a help message (What parameter parser libraries are there for C++?).
Remark, the argv+1 is used because by convention, the fist parameter is the name of the program.
This will print out all the command line arguments. Modify the code to do whatever you want
for(int i = 0; i < argc; i++)
std::cout << "argument " << i << ": " << argv[i] << std::endl;

C++ input conversion to lowercase for ignoring words written in upper case [duplicate]

This question already has answers here:
Case-insensitive string comparison in C++ [closed]
(30 answers)
Closed 7 years ago.
I wanted to make a sample code that asks the user for the "secret" code. The user has 5 tries to type in the correct (secret) phrase, if the user fails, the program closes itself. I have done everything, I just have one problem. If the user types in the secret phrase in uppercase letters, the program interprets it as wrong. I have seen some conversion methods but none have worked. Here is the code I have at the moment. I only need it to convert the input to lowercase:
int nextReveal(){
std::string code;
std::string answer = "sample";
for (int i = 1; i <= 5; i++){
//std::cout << " " << std::endl;
std::cout << "Type in the secret password" << std::endl;
std::cin >> code;
int tries = 5 - i;
if (code != answer && code != answer2 && code != answer3 ){
std::cout << "You have " << tries << " tries left before program self-destructs" << std::endl;
if (tries == 0){
std::cout << " You have used up all your tries. Program is closing" << std::endl;
return 1;
}
}
else if (code == answer){
std::cout << "Unlocked" << std::endl;
//i = 6;
return 0;
}
}
}
Your best approach will be to use tolower() method. In C++, a locale-specific template version of this function (tolower) exists in header .