#include <iostream>
#include <string>
struct Car{
std::string model;
unsigned int year;
};
int main(){
using namespace std;
int carNum;
cout << "How many cars do you wish you catalog? ";
cin >> carNum;
Car * cars = new Car[carNum];
for (int i=0;i<carNum;i++){
cout << "Car #" << i << endl;
cout << "Please enter the make: ";
getline(cin, cars[i].model);
cout << "Please enter the year made: ";
cars[i].year = cin.get();
}
cout << "Here's your collection" << endl;
for (int i=0;i<carNum;i++){
cout << cars[i].model << " " << cars[i].year << endl;
}
delete [] cars;
return 0;
}
When i execute the program, the getline(cin, car[i].model) just get skipped over. Why is this?
like this:
Car #2
Please enter the make: Please enter the year made:
Simple reason.
When you do cin >> whatever, a \n is left behind (it was added when you pressed Enter). By default, getline reads until the next \n, so the next read will simply read an empty string.
The solution is to discard that \n. You can do it by putting this:
cin.ignore(numeric_limits<streamsize>::max(),'\n');
Just after the cin >> carNum.
Don't forget to include limits in order to use numeric_limits.
After every cin call using insertion operator. You must call cin.ignore() if you want cin.getline () to work.
As cin>> leaves behind a '\n' character when you press enter and because of that when you use getline () it picks up the \n
and takes no input as it finds \n in the input stream which is the default delimiter.
So you can either do cin.ignore () after every cin>> or simply set a delimiter character cin.getline ()
Related
My program Can read strings and integer, but the problem is when I add spaces for strings like names it does not execute the viewOrder() function. I am New to programming and start learning c++ as my frist language at 19 years old, hoping that someone can help me. I am doing an uniform ordering system.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct orderDetails{
string name;
int studentNumber;
string address;
string dressCode;
int quantity;
};
void takeOrder(){
orderDetails order;
ofstream file ("database.dat" , ios::app);
cin.ignore();
cout << "Enter name: ";
getline(cin,order.name);
cout << "Enter Student Number: ";
cin >> order.studentNumber;
cin.ignore();
cout << "Enter Address: ";
getline(cin,order.address);
cout << "Enter Dress Code: ";
cin >> order.dressCode;
cout << "Enter Quantity: ";
cin >> order.quantity;
file << order.name << endl
<< order.studentNumber << endl
<< order.address << endl
<< order.dressCode << endl
<< order.quantity << endl;
file.close();
}
void viewOrder(){
ifstream database("database.dat");
orderDetails order;
while(database >> order.name >> order.studentNumber >> order.address >> order.dressCode >> order.quantity){
cout << endl << order.name << endl << order.studentNumber << endl << order.address << endl << order.dressCode << endl << order.quantity << endl;
}
}
int main(){
cout << "1.Take Order \n2.View Order \n3.Exit \nPlease Choose A Number: ";
int choice;
cin >> choice;
switch(choice){
case 1:
system("CLS");
takeOrder();
break;
case 2:
system("CLS");
viewOrder();
break;
default:
break;
}
return 0;
}
This is an old problem. You need to learn about the difference between formatted and unformatted input.
If you have a line of text like
abc def
and you read this into std::strings with
inputFileStream >> s1 >> s2
Then the input "abc" and "def" will be read into the to string-variables. Ok. But, the newline ('\n') at the end of the line will not be consumed. If you write an additional
inputFileStream >> s1 >> s2
to read the next line, then the inserter operator >> will skip the whitespace '\n' and read the strings as you would expect.
But, if you use std::getline after the initial formatted input, then, and remember that there is still a not-consumed '\n' at the end of the line, only an empty string and the newline will be read.
To overcome this situation, you can use std::ws. Please see here for a description. So, you simply add this in your std::getline statement.
Like this:
std::getline(ifs >> std::ws, line);
This will eat up all white spaces (including '\n') in front of the next text that you want to read.
To explain it better. This is a nested statement. So, first ifs >> std::ws is executed. This operation returns again ifs and then the std::getline will be done. You can of course also use ifs >> std::ws outside of the std::getline. That is in most cases better than calling ignore.
But remember. This is only necessary, if you switch from formatted to unformatted input.
I read some answers regarding how to fix it but I'm trying to also understand the concept behind it (i.e. why does the first getline work fine).
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main(){
string ticker = "";
string date = "";
int pprice;
int sprice;
cout << "Enter the stock ticker =>" << endl;
getline(cin, ticker);
cout << "Enter the purchase price =>" << endl;
cin >> pprice;
IT WORKS FINE UNTIL IT GETS TO HERE:
cout << "Enter the sell date =>" << endl;
getline(cin, date);
cout << "Enter the sell price =>" << endl;
cin >> sprice;
cout << ticker << endl;
return 0;
}
/*OUTPUT:
Enter the stock ticker =>
XYZ
Enter the purchase price =>
12.34
Enter the sell date =>
Enter the sell price =>
12.34
XYZ
*/
You're probably not using cin.ignore() in the correct place. It should be used after std::cin and before getline().
For Example:
int x;
string y;
cin >> x;
cin.ignore(INT_MAX);
getline(cin, y);
The idea is to remove the carriage returns, newlines etc that cin leaves behind on the stream which cause getline() to immediate take and return.
I'm working through some beginner exercises on c++, and this has me stumped. I can enter a number, but I don't get the option to enter a character afterwards, and it skips to the final line.
I know I can use cin >> symbol, but i would like to know why this isn't working.
#include<iostream>
using namespace std;
int main() {
cout << "Enter a number:\n";
int number;
cin >> number;
char symbol;
cout << "Enter a letter:\n";
cin.get(symbol);
cout << number << " " << symbol << endl;
return 0;
}
You should remove '\n' from stream, remained after entering the number:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Without it you will read newline character. You could check that with:
std::cout << (symbol == '\n') << std::endl;
\n will remain in the buffer after the first cin. You can solve this problem by adding an empty cin.get() between two consecutive reads.
cin.get(string1,maxsize);
cin.get();
cin.get(string2,maxsize);
Or you can use fflush:
cin.get(string1,maxsize);
fflush(stdin);
cin.get(string2,maxsize);
int x=0;
string fullname = "";
float salary;
float payincrease;
float newsal;
float monthlysal;
float retroactive;
while(x<3){
cout << "\n What is your full name?";
cin >> fullname;
cout << "\n What is your current salary? \t";
cin >> salary;
cout << "\n What is your pay increase? \t";
cin >> payincrease;
newsal = (salary*payincrease)+salary;
monthlysal = newsal/12.00;
retroactive = (monthlysal*6)-(salary/2);
cout << "\n" << fullname << "'s SALARY INFORMATION";
cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
x++;
}
My loop doesn't seem to stop for every time cin is asked, and instead instantly executes the loop 3 times on its own. How do I get it to stop when input is asked?
If the input stream isn't empty when you call cin, then cin uses the data already in the buffer instead of waiting for more from the user. You're using the extraction operator, so when cin is sending values to your variables, it skips leading whitespace in the buffer and stops on the next whitespace.
Put a breakpoint on this line:
cout << "\n What is your current salary? \t";
Run the program, and enter Bob Smith. When you hit the break point, hover your cursor over your string fullname. You'll see it stores only "Bob" not "Bob Smith". "Bob Smith" got put into the buffer, but when you use cin with the extraction operator, it skips any leading whitespace, puts the next value it finds into your variable, then stops on the next whitespace. To demonstrate this, try running this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1,str2;
cin >> str1;
cin >> str2;
cout << str1 << " " << str2 << "\n\n";
return 0;
}
If you type in "Bob Smith", it will take your input only one time, even though you call cin twice. However, you'll see that both "Bob" and "Smith" got captured in the strings str1 and str2.
Therefore, you can conclude that cin stops populating your string fullname when it gets to the space between Bob and Smith. On your next call to cin, the buffer still contains "Smith", so instead of taking more input from the user, it attempts to fill your variable salary with "Smith". Obviously this isn't want you want to do. You can call flush and ignore on cin to wipe out the buffer before every time you use cin, or instead you could fix your logic and use getline to take in the full name, including spaces.
To fix your problem, all you need to do is use getline instead of cin >>, so replace this line:
cin >> fullname;
with this:
getline(cin,fullname,'\n');
Secondly, you're using a while loop to execute a set of actions a specific number of times. That's typically something you'd use a for loop for.
As an aside, you could also write tiny input validation loops that can help you debug or otherwise avoid attempting to put invalid input into your variables (such as "Smith" into a float). Something like this could work:
for(;;)
{
if(cin >> salary)
break;
cin.clear();
cin.ignore(INT_MAX,'\n');
}
Note that cin returns a value, so you can use it in an if statement. If it gets valid input, it will return true. If not, it will return false. To make it more explicit, you could also just use a normal call to cin without the if statement, and then check if cin.good(), which amounts to basically the same net effect. If you're not using Visual Studio and get an error about INT_MAX, you might need to #include limits.h to resolve it.
That occurs if you input a char where an int is expected.
Use cin.clear(); and cin.ignore(numeric_limits<streamsize>::max(), '\n'); to limit an input to int's only.
Other than that, it won't skip if the correct data type is put in.
#include <string>
#include <iostream>
#include <limits>
using namespace std ;
int main(void)
{
int x=0;
string fullname = "";
float salary;
float payincrease;
float newsal;
float monthlysal;
float retroactive;
while(x<3)
{
cout << "\n What is your full name?";
cin >> fullname;
cin.ignore( 1000, '\n' );
cout << "\n What is your current salary? \t";
cin >> salary;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "\n What is your pay increase? \t";
cin >> payincrease;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
newsal = (salary*payincrease)+salary;
monthlysal = newsal/12.00;
retroactive = (monthlysal*6)-(salary/2);
cout << "\n" << fullname << "'s SALARY INFORMATION";
cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
x++;
}
cout<<" \nPress any key to continue\n";
cin.ignore();
cin.get();
return 0;
}
Check your variable types, I noticed mine accepting a digit instead of a character, had the same problem (not stopping, loop just kept going on).
> std::cin >> this->controls.button
> DETOX_NUMBER button; // (int)
Change to:
> char button;
Its been a while since i have coded c++ and i have forgot an annoying thing that happens when you gather string input. Basically if this loops back through, say if you use negative numbers then it skips the cin from the employee name line the second go round. I remember having this issue before and having to clear or do something of that sort before or after the string is input. Please help!
PS Also for extra help can anyone help me with a correct loop below. How can i check for a value in the string input to make sure they input a value?
#include <string>
#include <iostream>
#include "employee.h"
using namespace std;
int main(){
string name;
int number;
int hiredate;
do{
cout << "Please enter employee name: ";
getline(cin, name);
cout << "Please enter employee number: ";
cin >> number;
cout << "Please enter hire date: ";
cin >> hiredate;
}while( number <= 0 && hiredate <= 0 && name != "");
cout << name << "\n";
cout << number << "\n";
cout << hiredate << "\n";
system("pause");
return 0;
}
You want to change your loop condition to be whether or not any of the below are not set. The logical AND will only trigger if all three are unset.
do {
...
} while( number <= 0 || hiredate <= 0 || name == "");
Next, use cin.ignore() as prescribed by #vidit to get rid of issues with reading in newline characters.
Lastly, and importantly, your program will run an infinite loop if one enters an alphabetic character for an integer instead of...an integer. To mitigate that, use isdigit(ch) from the <cctype> library.
cout << "Please enter employee number: ";
cin >> number;
if(!isdigit(number)) {
break; // Or handle this issue another way. This gets out of the loop entirely.
}
cin.ignore();
cin leaves a newline character(\n) in the stream, which causes the next cin to consume it. There are many ways of getting around that. This is one way.. using ignore()
cout << "Please enter employee name: ";
getline(cin, name);
cout << "Please enter employee number: ";
cin >> number;
cin.ignore(); //Ignores a newline character
cout << "Please enter hire date: ";
cin >> hiredate;
cin.ignore() //Ignores a newline character