How to terminate the '\n' for std::cin.get() [duplicate] - c++

This question already has answers here:
std::cin input with spaces?
(8 answers)
Closed 5 years ago.
I would like to know how to get rid of the '\n' for when I execute cin.get(). For example:
#include <iostream>
int main() {
std::cout << "How many pieces of c: ";
struct c{
std::string name;
int val;
};
int amount;
std::cin >> amount;
c * c1 = new c[amount];
std::cin.get();
for(int i = 0; i < amount; i++){
std::cout << "C Number " << i + 1 << ":" << std::endl;
std::cout << "Please enter the name: ";
c1[i].name = std::cin.get();
std::cout << "Please enter the val: ";
std::cin >> c1[i].val;
std::cin.get();
}
return 0;
}
I've tried using cin.get() to eliminate the '\n' thats last read after my std::cin, but my program only takes in the first name and then executes the rest of the program without letting me continue to type the rest of the name and val values. In short, I want to be able to store the rest of my name and val values. Thanks!

c1[i].name = std::cin.get();
I'm not sure why you used get() instead of operator >>, like you did two lines later. get() reads a single character - meaning, only the first character you type in is saved as name. Everything else is read (most likely unsuccessfully) into val, and then new line character is, just like you intended, digested by the final get().

For reading int, try using getline and stringstream:
std::string input(5, '\0');
int number;
std::getline(std::cin, input);
std::stringstream sstrm(input);
sstrm >> number;
For a name: You can directly use getline
std::string name(30, '\0');
std::getline(std::cin, name);

Related

Creating a struct during while loop skips over input [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 1 year ago.
I'm trying to create a struct and collect its inputs from the user with a while loop, however on the second iteration it just seems to skip past the inputs.
#include <iostream>
#include <list>
struct Student {
std::string name;
std::string course;
float mark;
};
int main() {
std::list<Student> students;
while (students.size() < 2) {
Student student;
std::cout << "Student Name:" << std::endl;
std::getline (std::cin, student.name);
std::cout << "Course and Mark:" << std::endl;
std::cin >> student.course >> student.mark;
students.push_back(student);
}
for(auto const& student: students) {
std::cout << student.name << std::endl;
}
return 0;
}
The output looks like so:
Student Name:
Ari Stackoverflow
Course and Mark:
course543 56.2
Student Name: <---- skipped :(
Course and Mark:
Steve Jobs
As you can see, one the second iteration it skips over getting the name, not sure why.
The problem here is that when you press "Enter" after your second line of input, that newline is fed to std::getline(std::cin, student.name); on the next iteration. And so students[1].name would be an empty string.
To get around this, add std::cin.ignore() or std::cin.get() after reading your second line. This tells cin to ignore the newline.

C++ Why is my first data input with getline(cin, array[x]) is on the sameline and broken while my 2nd data input is fine? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 2 years ago.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int person;
cout << "How many person to data: ";
cin >> person;
int x = 0;
int i = 1;
string name[person];
string adress[person];
while(x < person){
cout << i << " person data" << endl;
cout << "Name: ";
getline(cin, name[x]);
cout << "Adress: ";
getline(cin, adress[x]);
cout << endl;
x++, i++;
}
for(x=0; x<person; x++){
cout << name[x] << setw(15) << adress[x] << endl;
}
}
This is my code to store a name and an adress into an array name[] and adress[]
And then i use for loop to print their name and adress
This is output image
Result
Why is my 1 person data broken?
The name and adress is on the same line while my 2nd person data is fine?
Its fine if i use cin >> but i use getline so i can a full name and an adress with the spaces
For starters variable length arrays
string name[person];
string adress[person];
is not a standard C++ feature. Instead use the standard container std::vector<std::string> like
#include <vector>
//...
std::vector<std::string> name( person );
std::vector<std::string> adress( person );
Or instead of two vectors you could declare a vector of objects of the type std::pair<std::string, std::string> like
#include <utility>
#include <vector>
//...
std::vector<std::pair<std::string, std::string>> persons( person );
In this case you should write in the loop like
//...
getline(cin, persons[x].first );
//...
getline(cin, persons[x].second);
After this input
cin >> person;
the input stream contains the new line character '\n' that corresponds to the pressed key Enter. You need to remove it before the while loop like
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
To do this you need to include the header <limits>.

Why won't getline function work multiple times in a for loop with an array of structures? [duplicate]

This question already has answers here:
Why does std::getline() skip input after a formatted extraction?
(5 answers)
Closed 7 years ago.
I have a little problem. I've created a program that asks user to enter part's name and part's price for four diffrent parts. Each name and price fills a structure, and I have an array of four structures. When i do a for loop to fill all the names and prices, my getline functon doesn't work properly, it simply just skipps the entering part after I enter the first part's name. Can you please tell me why?
Here's my code:
#include <iostream>
#include <string>
struct part {
std::string name;
double cost;
};
int main() {
const int size = 4;
part apart[size];
for (int i = 0; i < size; i++) {
std::cout << "Enter the name of part № " << i + 1 << ": ";
getline(std::cin,apart[i].name);
std::cout << "Enter the price of '" << apart[i].name << "': ";
std::cin >> apart[i].cost;
}
}
std::getline consumes the newline character \n, whereas std::cin will consume the number you enter and stop.
To illustrate why this is a problem, consider the following input for the first two 'parts':
item 1\n
53.25\n
item 2\n
64.23\n
First, you call std::getline, which consumes the text: item 1\n. Then you call std::cin >> ..., which recognises the 53.25, parses it, consumes it, and stops. You then have:
\n
item 2\n
64.23\n
You then call std::getline for a second time. All it sees is a \n, which is recognised as the end of a line. Therefore, it sees a blank string, stores nothing in your std::string, consumes the \n, and stops.
To solve this, you need to make sure the newline is consumed when you store the floating-point value using std::cin >>.
Try this:
#include <iostream>
#include <string>
// required for std::numeric_limits
#include <limits>
struct part {
std::string name;
double cost;
};
int main() {
const int size = 4;
part apart[size];
for (int i = 0; i < size; i++) {
std::cout << "Enter the name of part № " << i + 1 << ": ";
getline(std::cin,apart[i].name);
std::cout << "Enter the price of '" << apart[i].name << "': ";
std::cin >> apart[i].cost;
// flushes all newline characters
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}

C++ User defined string needs to contain spaces (but not allowed by program..?)

I'm working on homework for my c++ class, and it's been quite awhile since I've used it. I was wondering if there was a way to allow spaces in a string (instead of it nulling out and ending the string)
my current code is this:
int chapter10() {
string strinput;
char charstr[1000];
int numwords=1;
cout << "Enter a phrase ";
cin >> strinput;
cout << strinput;
const int size = strinput.size() + 1;
strcpy_s(charstr, strinput.c_str());
cout << strinput << endl;
for (int i = 0; i != size; i++) {
if (*(charstr + i) == ' ')
numwords++;
}
cout << "There are " << numwords << " words in that string." << endl;
return 0;
}
The problem I'm having, is for instance, if I type "Hello World" and press enter, it pops the next line (right after the cin) and says "Hello", and the space made it cut the rest of the phrase off.
How does one fix this issue? I don't want to use the str:: things as I barely know what they are, and have really never had to use them, and that would look a bit suspicious to the teacher :P
Update: If you've suggested using getline(cin, strinput); It doesn't work too well. I can from what I see, only type in the 10 to reach my function, but after I press enter, it thinks that I've presses something else, which makes it completely skip the cin to get the string value. But, there is something weird with this, if I type "10 hello world" it does everything correctly. Well, with the exception that it needs to be in the same line as the number to reach the function.
Solved: The use of getline(cin, strinput) works perfectly fine, if you're not using user input before hand. If you are, you're going to need a cin.ignore before the getline(). As stated in the comment by my best answer.
#include <iostream>
#include <iomanip>
#include <string>
#include <limits>
using namespace std;
//~~~Initialize all functions
int chapter10();
//~~~Initializing complete
int main() {
srand(time(0)); //makes rng thingy work instead of choose same numbers cause it doesn't do it on its own. lol
cout << "Enter the chapter number you need to look at: ";
int chapterNumber;
cin >> chapterNumber;
switch (chapterNumber) {
case 1: testingStuff(); break;
case 9: chapter9(); break;
case 10: chapter10(); break;
default: cout << "You chose an invalid chapter number, reload the program."; break;
}
system("pause");//So console doesn't close instantly cause that's not annoying at all...
}
int chapter10() {
string strinput;
char charstr[10000];
int numwords=1;
cout << "Enter a phrase." << endl;
cin.ignore(numeric_limits<streamsize>::max(), '\n');
getline(cin, strinput);
const int size = strinput.size() + 1;
strcpy_s(charstr, strinput.c_str());
for (int i = 0; i != size; i++) {
if (*(charstr + i) == ' ' & *(charstr + (i+1)) != ' ' )//the & is fail safe so multiple space no ++numwords
numwords++;
}
cout << "There are " << numwords << " words in that string." << endl;
return 0;
}
The way I have my code written was I used a switch/case to reach my function. This required user input, which in turn caused my program to 'think' I was still typing for the second input required in the chapter10 function.
Adding in the line of code: cin.ignore(numeric_limits<streamsize>::max(), '\n'); allowed me to cancel the input, and start a new one.
If you want to get all characters an end-user enters on a single line, use getline: instead of cin >> strinput write this:
getline(cin, strinput);
The fact that it is actually std::getline(std::cin, strinput) makes no difference, because your code uses std namespace anyway. In case you were wondering what std:: prefix is, it's a namespace of the Standard C++ library.
You can use getline() function
It copies into a string till a newline is reached or delimiter is found - so it will accept all the spaces till newline is reached
http://www.cplusplus.com/reference/string/string/getline/
or you can also use cin.getline() as shown here -
std::cin input with spaces?
use:
cin >> noskipws >> strinput;
Use std::getline() function. Example:
#include <iostream>
#include <vector>
#include <sstream>
void WordCounter(
const std::vector<std::string> & lines) {
for (int i = 0; i < lines.size(); ++i) {
std::istringstream iss(lines[i]);
std::string word;
int count = 0;
while (iss >> word) {
++count;
}
std::cout << "Line #" << i << " contains " << count << " words." <<
std::endl;
}
}
int main() {
std::string line;
std::vector<std::string> lines;
while (std::getline(std::cin, line)) {
lines.push_back(line);
}
WordCounter(lines);
return 0;
}

C++ STD Cin error in while loop

Why when I entered the loop below and I type something the first instruction
cmdstd:getline(std::cin,cmdInput); does not read the input entered. For instance if I entered "b 8" it should display "cmd is b 8", but it skips to the next read std::getline(std::cin, input); and displays "it is b" instead
while (editingMode == TRUE) {
std::getline(std::cin, cmdInput);
istringstream cmdiss(cmdInput);
cout << "you entered: " << cmdInput <<endl;
if (cmdInput != "") {
copy(istream_iterator<string>(cmdiss),
istream_iterator<string>(),
back_inserter<vector<string> >(tokens));
std::cout << "cmd is " <<tokens.at(0) << std::endl;
}
//*************************
std::getline(std::cin, input);
istringstream iss(input);
if(input != ""){
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter<vector<string> >(tokens));
std::cout << "it is " << tokens.at(0) <<std::endl;
createInstruction(tokens);
}
Perhaps you have a newline character left in the input buffer, from an earlier input? This is a common error.
Lets say that your program first reads an integer with cin >> x, and then a line with getline(cin, cmdline). The user types an integer, followed by the ENTER key. The cin >> x will read the integer, but the ENTER key, interpreted as a newline character, will be left in the input buffer.
When your program then goes on to read a complete line with getline(cin, cmdline), it will read the very short line that consists of just that left-over newline character. This looks like the program "skips to the next read".
There's nothing wrong with the code. It just doesn't do what you think it should :) If you want to print the whole line entered rather than the first word, don't print tokens[0]; print the input line.
Both sections do the same thing:
read a line into a string
create an istream from that line
read the words from that istream into an array of strings called 'tokens'
print the first word
tokens.at(0) is the first word, obviously. check tokens.size() or iterate over tokens if you want to look for arguments like "8".
are you sure editingMode is TRUE?
The problem is mixing >> extractions with getline, leaving a newline (or other input) in the buffer. Blindly using ignore will hide logic errors, such as input of "42 abc" followed by cin >> some_int; cin.ignore(...);. What you really have to do is "extract" the blank line:
int main() {
using namespace std;
int n;
string s;
cout << "Enter a number: "
cin >> n >> blankline; // <---
if (cin) {
cout << "Enter a line of text: ";
getline(cin, s);
}
if (!cin) {
clog << "Sorry, I can't do that.\n";
return 1;
else {
cout << "Input successful, now processing values: " << n << s << '\n';
}
return 0;
}
Thankfully, this is easy:
template<class C, class T>
std::basic_istream<C,T>&
blankline(std::basic_istream<C,T>& s,
typename std::basic_istream<C,T>::char_type delim) {
if (s) {
typename std::basic_istream<C,T>::char_type input;
if (!s.get(input) && s.eof()) {
s.clear(s.eofbit);
}
else if (input != delim) {
s.putback(input);
s.setstate(s.failbit);
}
}
return s;
}
template<class C, class T>
std::basic_istream<C,T>& blankline(std::basic_istream<C,T>& s) {
blankline(s, s.widen('\n'));
return s;
}