I'm making a small desk cost program for a class. I wanted to include a loop into it. But every time I get to the end of the program and loop it back to the beginning, it skips the part where I ask for the customers name and leaves it blank. Any idea how to fix it?
Here's my code:
#include <iostream> // needed for Cin and Cout
#include <string> // needed for the String class
#include <math.h> // math functions
#include <stdlib.h>
using namespace std;
#define baseCost 200.00
#define drawerPrice 30.00
int main(void)
{
while(true)
{
string cname;
char ch;
cout << "What is your name?\n";
getline(cin, cname);
cout << cname;
cout << "\nWould you like to do another? (y/n)\n";
cin >> ch;
if (ch == 'y' || ch == 'Y')
continue;
else
exit(1);
}
return 0;
}
The problem is that you need to call cin.ignore() after your prompt for exit. When you use cin to get the 'ch' variable, a newline character is still stored in the input buffer. Call cin.ignore(), to ignore that character.
If you don't, you'll notice that the program prints a newline as the name on the second loop.
You could also make the 'ch' variable a string like 'cname' and use getline instead of cin. Then you wouldn't have to issue the cin.ignore() call.
#include <iostream> // needed for Cin and Cout
#include <string> // needed for the String class
#include <math.h> // math functions
#include <stdlib.h>
using namespace std;
#define baseCost 200.00
#define drawerPrice 30.00
int main()
{
while(true)
{
string cname;
char ch;
cout << "What is your name?\n";
getline(cin, cname);
cout << cname;
cout << "\nWould you like to do another? (y/n)\n";
cin >> ch;
// Slightly cleaner
if (ch != 'y' && ch != 'Y')
exit(1);
cin.ignore();
/*
if (ch == 'y' || ch == 'Y')
continue;
else
exit(1);
*/
}
return 0;
}
Related
I have two consecutive inputs, however, my program ends before allowing me to have my second input and just runs till the end, so:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<double>v1;
for(double temp1; cin >> temp1;)
v1.push_back(temp1);
cout << "input1";
vector<double>v2;
for (double temp2; cin >> temp2;)
v2.push_back(temp2);
cout << "input2";
return 0;
}
I will be given the opportunity for input in the first for loop, however, after that, it doesn't let me give a second input and just goes on to print "input2".
It is ok to use the fail state of std::cin this way. You just need to reset std::cin before it can be used again.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<double>v1;
for(double temp1; cin >> temp1;)
v1.push_back(temp1);
cin.clear(); //clear the error
cin.ignore(1000, '\n'); //ignore characters until we reach \n
cout << "input1";
vector<double>v2;
for (double temp2; cin >> temp2;)
v2.push_back(temp2);
cout << "input2";
return 0;
}
You could also #include <limits> and call
cin.ignore(numeric_limits<streamsize>::max(),'\n');
instead, to ignore unlimited characters until \n is reached.
I wanted to grab a 10 character and store it in cstring and ignore the rest but I have having problem with it. The program doesn't halt for input the next time. How can I make it so that it halts and lets me enter again.
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
char arr[11] = " "; //This is a cstring
string x; //will test with this variable
cout <<"Enter 10 character, rest will be ignored: \n";
cin.getline(arr, 10,'\n');
cin.ignore();
cout <<"Testing..\n";
cin >>x; //Should make the program halt
cout <<arr <<endl;
cout <<x;
}
cin.getline(arr, 10,'\n') will output at most 9 characters, not 10 characters, stopping if a line break is read before reaching 9 characters. If you want to receive 10 characters, you need to set the count parameter to 11 - the full size of arr - to include room for 10 characters + the null terminator.
Calling cin.ignore() afterwards without any parameters will ignore only 1 character. So, if the user types in more than count+1 characters, you are not ignoring them all. You should tell cin.ignore() to ignore all characters up to the next line break, if no line break was reached during the read.
Try this instead:
#include <iostream>
#include <string>
#include <limits>
using namespace std;
int main()
{
char arr[11]; //This is a cstring
string x; //will test with this variable
cout << "Enter 10 character, rest will be ignored: \n";
if (cin.getline(arr, 11, '\n'))
{
// <= 10 characters w/ line break were read
}
else
{
if (cin.fail() && !cin.bad()) // exactly 10 characters w/o a line break were read, ignore the rest...
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
cout << "Testing..\n";
cin >> x; //Should make the program halt
cout << arr << endl;
cout << x;
}
That being said, this is C++, not C. It would be easier to use std::getline() instead, eg:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str; //This is a c++ string
string x; //will test with this variable
cout << "Enter 10 character, rest will be ignored: \n";
getline(cin, str);
if (str.size() > 10)
str.resize(10);
cout << "Testing..\n";
cin >> x; //Should make the program halt
cout << str << endl;
cout << x;
}
I'm writing a console application for managing and tracking characters, monsters, turn order and conditions applied to make my battle run faster in DnD. The following code works perfectly on Windows but when I tried to compile it on my laptop, which runs Linux, it no longer works.
I input a name, then the initiative, then max health, then when I go to add another character it just reads a blank string and sets that as the name. I'm at a loss...
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
void gValid_Input(std::string& var, std::string question = "Add the carriage return manually if you want it...") {
using namespace std;
do {
cin.clear();
cin.sync();
cout << question;
} while (!getline(cin, var));
}
template <typename t>
void gValid_Input(t& var, std::string question = "Add the carriage return manually if you want it...") {
using namespace std;
do {
cin.clear();
cin.sync();
cout << question;
} while (!(cin >> var));
}
void gValid_Option(char& response, std::vector<char> valid_Responses = {'y','n'}){
using namespace std;
const char diff = 'a' - 'A';
do{
cin.clear();
cin.sync();
cin >> response;
if (response >= 'A' && response <= 'Z'){
response += diff;
}
} while (find(valid_Responses.begin(), valid_Responses.end(), response) == valid_Responses.end());
}
void gValid_Option(char& response, std::string question, std::vector<char> valid_Responses = {'y','n'}){
using namespace std;
const char diff = 'a' - 'A';
do{
cin.clear();
cin.sync();
cout << question;
cin >> response;
if (response >= 'A' && response <= 'Z'){
response += diff;
}
} while (find(valid_Responses.begin(), valid_Responses.end(), response) == valid_Responses.end());
}
SOLVED
void gValid_Input(std::string& var, std::string question = "Add the carriage return manually if you want it...") {
using namespace std;
do {
cin.clear();
cin.sync();
cout << question;
if (cin.peak() == '\n'){
cin.ignore(1, '\n');
}
} while (!getline(cin, var));
}
The task is to cin>>...., take only letters, change upper case letters to lower case and rewrite line with only lower case letters. I cannot figure out why my code is ignoring the first letter entered.
#include <iostream>
#include <cctype>
using namespace std;
int main()
{
char ch;
cin >> ch;
while (ch != '#'){
if (cin.get(ch))
{
if (isalpha(ch)){
if (isupper(ch)){
cout <<(char)tolower(ch);
}
else
cout << ch;
}
if (ch == '\n')
cout << "\nNie zakonczyles ciagu znakiem #" << endl;
}
else{
cin.clear();
}
}
}
Because the loop uses cin.get(ch) to get the character to print, but the first character is actually read with cin >> ch; and then the result is discarded.
You might want to get rid of the cin>>ch; instruction and initialize ch to a value different from '#', or transform the loop into a do-while loop, similar to this:
char ch;
do
{
if (cin.get(ch))
{
/* Do what is needed */
}
}
while (ch != '#')
cin >> ch; <- read first letter
while (ch != '#'){
if (cin.get(ch)) <- read next letter which tosses out the first letter
To fix this set ch to some value and then get rid of cin >> ch;
Because just after cin >> ch; you're doing cin.get(ch).
Hey guys so I'm writing a program where I can only in one letter(ex. a,b,c) and I want the program to exit if the user tries to enter anything else ex)string int etc. The code sample I have so far is this. When I try to run this it the program will always say that the input is a letter.
#include <iostream>
using namespace std;
int main(){
char guess;
bool isnotletter
cout<<"Enter your guess"<<endl;
cin>>guess;
isnotletter=cin.fail();//cin.fail returns true if the input is something that disagrees with the data type (ex string and int would)
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
if(isnotletter==true)
{
cout<<"Error"<<endl;
exit(1);
}
else
cout<<"You are a letter"<<endl;
}
A simple way to do this, including flushing the line in case of bad input, would be to read the whole line and see if it consisted of a single character:
std::string s;
if ( !getline( cin, s ) ) // reads a whole line
cout << "Error or end-of-file\n";
else if ( s.size() != 1 )
cout << "Input was not a single character\n";
else if ( !isalpha(s[0], locale()) )
cout << "Input was not a letter\n";
else
cout<<"You are a letter"<<endl;
Of course, you could combine some of those error conditions if you are not interested in specific error messages.
I think isalpha() function helps you.
Source
#include <iostream>
#include <ctype.h>
#include <string.h>
using namespace std;
int main(){
string guess;
cout<<"Enter your guess"<<endl;
cin>>guess;
if( (!isalpha(guess[0])) || (guess.size() > 1) )
{
cout<<"Error"<<endl;
return -1;
}
else
cout<<"You are a letter"<<endl;
return 0;
}
cin.fail() will return true if there is an exception thrown when assigning a value, that much is correct. However, using cin to receive a string and assign it to a character doesn't throw an exception, as what happens is that cin simply takes the first character in the input buffer and assigns it to guess, leaving the rest of the string in queue within the input buffer. This is considered acceptable by cin.
In your code, if the user had written "hello", guesswill have the character h. If you use another cin below, and assign it to let's say char mychar, it won't ask the user again, as there is still input waiting. Instead, it'll assign the next character e to mychar.
Example:
#include <iostream>
using namespace std;
int main(){
char guess;
char mychar;
bool isnotletter;
cout<<"Enter your guess"<<endl;
cin>>guess;
isnotletter=cin.fail();
//cin.fail returns true if the input is something that disagrees with the data type (ex string and int would)
cin>>mychar;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
if(isnotletter==true)
{
cout<<"Error"<<endl;
exit(1);
}
else
cout<<"You are a letter"<<endl;
system("pause");
return 0;
}
The second char mychar will receive the second character in the first string input, without asking for the user to input again.
A solution could be using a string to get all the inputs, and if you want then you can assign the first letter of the string to your char. Later, you can use if and measure the string size, and if it is >1 then output the Error message.
#include <iostream>
#include <string>
using namespace std;
int main(){
string myString;
char mychar;
cout<<"Enter your guess"<<endl;
cin >> myString;
mychar = myString[0];
cin.ignore(numeric_limits<streamsize>::max(),'\n');
if(myString.size() > 1)
{
cout<<"Error"<<endl;
//exit(1);
}
//Code to check for numbers
else if(string::npos != myString.find_first_of("0123456789"))
{
cout << "digit(s)found!" << std::endl;
}
else
cout<<"You are a letter"<<endl;
system("pause");
return 0;
}
For text validation, regex is quiet of a powerful tool in general (can be slow though).
regex charRegex("(\\+|-)?[[:alpha:]]+");
string input;
cout<<"Input : "<<endl;
cin>>input;
if(!regex_match(input,charRegex))
cout<<"Invalid input"<<endl;
Companion of every regex fanatic.