C++ Getline simple error [duplicate] - c++

This question already has an answer here:
What am I not understanding about getline+strings?
(1 answer)
Closed 7 years ago.
I would like to point I am not good in C++, I usually use C but i thought that get to know some C++ basic will be good so I need to send data to server and normal std::cin >> variable can't do it because it only reads input to space so I read about getline and it's working great, but when I do something liek this in infinite loop:
for (;;)
{
std::cout << "Hello" << std::endl;;
std::getline(std::cin,darek.wiadomosc);
}
Durning first itteration it shows on screen double Hello like:
Hello
Hello
String that is being entered
But after one loop it shows everything good. It's problem with getline I'm sure because when I changed it to std::cin >> just for test it worked. Can anybody answer to my simple question?

std::cin leaves the terminator in the stream (be it a space or a newline).
So if you do:
std::string foo, bar;
std::cin >> foo;
std::getline(std::cin, bar);
with input as:
Hello
World
bar will end up with the empty string, not "World", because getline will stop at the first newline, which is the one after "Hello".
To bring this back to your question, if you have instances of std::cin >> before the start of your loop, you may have a stray newline, making the first iteration behave in unexpected ways. You can use std::cin.ignore to ignore any newlines left in the stream.

Related

cin.get() isn't working as it should [duplicate]

This question already has an answer here:
Cin.get() issue with C++ [duplicate]
(1 answer)
Closed 9 years ago.
First, here is the code:
using namespace std;
cout << "\aOperation \"HyperHype\" is now activated!\n";
cout << "Enter your agent code:_______\b\b\b\b\b\b\b";
long code;
cin >> code;
cin.get();
cout << "\aYou entered " << code << ".....\n";
cout << "\aCode verified! Proceed with Plan Z3!\n";
cin.get();
return 0;
It compiles without a problem and runs almost without flaw; after 'code' receives its value from standard input, the final string flashes up for maybe a millisecond and the program dies. As you can see I placed the 'cin.get()' member function after the final string in order to prevent this, yet it continues to die after the 'cin >> code;' line.
This method has worked for all of my other practice programs up until now, and there is nothing structurally different between this program and any of the others.
Any suggestions?
(Assume proper header files and preprocessor directives are in place.)
You are reading the newline character you already entered earlier with your final get() call. You might want to ignore all characters up to and including the first newline before waiting for some other input:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.get();
You can shorten this to become
std::cin >> std::ws;
if it is OK requiring to enter a non-whitespace character to terminate the program: the std::ws manipulator extracts whitespace characters until either a non-whitespace character or the end of the stream is reached.
Note that std::istream::get() actually does work as it should! It just reads the next character. It just happens not to do what you did expect.
Add a cin >> code line instead of the two cin.get(). If the program just closes anyway, then this would probably be the simplest thing to do.

C++ Press Enter to Terminate Program [duplicate]

This question already has answers here:
Cin.Ignore() is not working
(4 answers)
Closed 9 years ago.
I am writing a C++ program and I need to program to end/terminate after the user hits enter.
This is what I have:
cout << "Press Enter to End" << endl;
cin.ignore(); //ends after the user hits enter
return 0;
But it doesn't work. Any advice?
I sense that you had some formatted input earlier in your program, i.e., it looks something like this:
std::cin >> value;
do_something(value);
std::cout << "press enter to end\n";
std::cin.ignore();
If that is the case, you have some character in the input buffer from the time you entered value. For example, there can be a '\n' but it can be any odd other characters, too. This character will be read when the program encounters std::cin.ignore().
What you probably want to is to get rid of the characters currently known to be in the buffer. This isn't quite what would be done as this can still miss characters which are already entered but not, yet, transferred but there is no portable approach to clear all potential characters (it is normally not a problem because hardly any user interface depends on character input from a terminal).
To ignore the characters which are known to be present you need to start off by breaking the connection between <stdio.h> and IOStreams using std::ios_base::sync_with_stdio() and later consume the known characters entered after your last read, e.g.,
#include <iostream>
int main()
{
std::ios_base::sync_with_stdio(false);
int x;
std::cin >> x;
std::cin.ignore(std::cin.rdbuf()->in_avail());
std::cout << "press enter\n";
std::cin.ignore();
}
The odd call to sync_with_stdio() is necessary to have the IOStreams actually buffer the characters received from the system rather than reading characters individually. As a nice side effect it dramatically improves the performance of using std:cin, std::cout, and the other standard stream objects.
maybe add system("pause") in the end of code; (include first). I guess you want enter to close termination.

Mixing ifstream getline and >> [duplicate]

This question already has answers here:
program skips over getline [duplicate]
(2 answers)
Closed 7 years ago.
After using a >> to input a float value, getline ceases to work correctly and reads trash. How can I avoid this?
string settingsFile = "TerrainSettings.txt";
ifstream settingsStream;
settingsStream.open(settingsFile.data());
assert (settingsStream.is_open());
string line;
getline(settingsStream,line); // fine here
getline(settingsStream,line); // fine here
getline(settingsStream,line); // fine here
float frequency;
float octaves;
float amplitude;
settingsStream>>frequency; // fine here
getline(settingsStream,line); // here it gets trash, why?
settingsStream>>octaves; // trash
getline(settingsStream,line);
settingsStream>>amplitude;
Edit: An inclusion of ignore(), generates the following error:
settingsStream>>frequency;
settingsStream.ignore(256,'\n');
getline(settingsStream,line); // fine here
settingsStream>>octaves; // trash here
getline(settingsStream,line);
settingsStream>>amplitude;
sample input:
/*Settings for Terrain Rendering, please input values on their respective lines*/
/**/
Frequency:
24
Octaves:
120
Amplitude:
1.25
First of all, start using std::strings and std::getline. Secondly, the reason for the trashing is that there's still a newline in the buffer. If you expect the user to be entering values one line at a time, you should use istream::ignore to skip everything up to and including the next newline character. For example:
std::string s;
float f;
std::cin >> f;
std::cin.ignore(big_num, '\n');
std::getline(std::cin, s);
What big_num should be depends on your expectations about the input. If you don't mind writing a lot and want to be on the safe side, use std::numeric_limits<std::streamsize>::max(). If you do mind writing a lot, make a constant of the suitable type that you use everywhere.
For example, the above code will parse the following so that f = 5.0f, s = Hello!.
5
Hello!
However, it will parse the following exactly the same way:
5 Hi!
Hello!
If you want to preserve the Hi!, you shouldn't ignore things, and instead define a proper grammar that you'll use to parse the document.

Getline problem [duplicate]

This question already has an answer here:
What am I not understanding about getline+strings?
(1 answer)
Closed 7 years ago.
I've got following code:
system("CLS");
string title;
string content;
cout << "Get title." << endl;
getline(cin,title);
cout << "Get content." << endl;
getline(cin,content);
The problem is - application is not asking about tittle, I've got Get title, get content and then waiting for user input, it's not waiting for user input after get title.bDo I have to add any break or smth?
Or maybe, that isn't the best idea to read whole text line from user input?
If you have a cin >> something; call prior to your system() call.
For example, taking input into an integer. When cin >> myintvar; (or similar) then the integer is placed in myintvar and the '\n' gets sent along in the stream. The getline picks the \n up as indicative of the end of a line of input, so it is effectively "skipped".
Either change the cin >> to a getline()
or call cin.ignore() to grab the '\n'(or better, call a cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n' ); to flush the input buffer-- but be sure you're not throwing away valuable input in the process).
I'd bet that you have something like a menu for selecting options ( as a numeric type ) and after that you try to read the lines.
This happens because after std::cin read some value the remaining '\n' was not processed yet, the solution would be to include #include <limits> and then put std::cin.ignore(std::numeric_limits<streamsize>::max(),'\n');
before your getline(cin,title);
It is because when you use getline() it ignores the newline at the end of the line and feeds it into the input queue, so when your getline function is called for next time it encounters the newline character discarded by the previous getline() and so it considers that as end of your input string. So thats why it doesn't take any input from you. You could use something like this
getline(cin,title);
cin.get();
hope this works.

C++: Why does space always terminate a string when read?

Using type std::string to accept a sentence, for practice (I haven't worked with strings in C++ much) I'm checking if a character is a vowel or not. I got this:
for(i = 0; i <= analyse.length(); i++) {
if(analyse[i] == 'a' || analyse[i] == 'e' [..etc..]) {
...vowels++;
} else { ...
...consonants++;
}
This works fine if the string is all one word, but the second I add a space (IE: aeio aatest) it will only count the first block and count the space as a consonant, and quit reading the sentence (exiting the for loop or something).
Does a space count as no character == null? Or some oddity with std::string?, It would be helpful to know why that is happening!
EDIT:
I'm simply accepting the string through std::cin, such as:
std::string analyse = "";
std::cin >> analyse;
I'd guess you're reading your string with something like your_stream >> your_string;. Operator >> for strings is defined to work (about) the same as scanf's %s conversion, which reads up until it encounters whitespace -- therefore, operator>> does the same.
You can read an entire line of input instead with std::getline. You might also want to look at an answer I posted to a previous question (provides some alternatives to std::getline).
I can't tell from the code that you have pasted, but I'm going to go out on a limb and guess that you're reading into the string using the stream extraction operator (stream >> string).
The stream extraction operator stops when it encounters whitespace.
If this isn't what's going on, can you show us how you're populating your string, and what its contents are?
If I'm right, then you're going to want a different method of reading content into the string. std::getline() is probably the easiest method of reading from a file. It stops at newlines instead of at whitespace.
Edit based on edited question:
use this (doublecheck the syntax. I'm not in front of my compiler.):
std::getline(std::cin, analyze);
This ought to stop reading when you press "enter".
If you want to read in an entire line (including the blanks) then you should read using getline. Schematically it looks like this:
#include <string>
istream& std::getline( istream& is, string& s );
To read the whole line you do something like this:
string s;
getline( cin, s );
cout << "You entered " << s << endl;
PS: the word is "consonant", not "consenent".
The >> operator on an istream separates strings on whitespace. If you want to get a whole line, you can use readline(cin,destination_string).