When i use while(cin >> word) { cout << word } program shows all the word i write one by one. But i cant understand why. When we use ints we write something like i++ to end the loop. My question is how does the program knows to write the next word and not the first word over and over again?
cin >> word does two separate things; it reads a word from the input (changing the state of cin) and then tells you whether it succeeded (so the loop knows when to terminate). Next time round the loop cin knows what you've already read and moves on to the next thing.
So it's a function with side-effects; as well as returning a result it also alters the state of the system. There are two views of this - it's a very bad idea that makes understanding code hard, and it's very useful for writing simple but powerful code. Both are true to some extent.
Because the condition cin >> word is executed in each iteration of the loop. Thus before the cout statement becomes executed, the cin statement is executed, setting word to the current entered string.
Related
I want to get user input, and the number of characters that are given is important. I get a satisfying result with input.empty() but it terminates after I press Enter. I want it to terminate after i specifically type Ctrl+D.
1) do{ 2) while(std::getline(std::cin, input)){
getline(std::cin, input); buffer += input;
buffer += input; buffer += '\n';
buffer += '\n'; }
}while(!input.empty()); std::cin.ignore();
Other than the Enter terminator the first code work as I want it to, and the second one has a character more, which I'm not sure what it exactly is, but it does end when I type Ctrl+D. input and buffer are both std::string. So how can I get the same result as input.empty().
Thank you in advance.
In your question, you claim that the second code snippet produces one character more in buffer than the first code snippet. However, I assume that this statement is false. It is the first one which should have one character more, for the following reason:
When std::getline encounters end-of-file after reading at least one character, then both code snippets will behave the same way.
However, if std::getline encounters end-of-file before reading at least one character (i.e. if it is encountered at the start of the line), then the behavior of the two code snippets is different: The first code snippet will write an additional newline character to buffer, before the loop gets terminated, whereas the second code snippet will terminate immediately.
In other words, the first code snippet produces one character too much, because its logic is wrong. Therefore, I suggest that you use the second snippet. However, it is unclear what std::cin.ignore(); in the second code snippet is supposed to accomplish, because the function std::getline has already removed the newline character from the input stream (if it existed). Also, calling std::ignore when the end of the stream has already been reached will probably have no effect. Therefore, you should probably remove that line.
I am new to C++, I have practically started it today. Any way, I am facing a problem where the first line contains two integers, and the next lines contain operations to be done. It's a fairly weird problem, actually, so I won't go into the details. Well, I am having a problem with reading the first line, and then the follow up operations.
My code looks like this so far:
int m, j;
string comando;
string OPR
cin << m << l;
while (getline(cin, comando)) {
OPR = comando.substr(0, 3);
}
The problem is: Apparently, whenever I write both m and l in the same line, the \n stays in the buffer, and it get's read by the newline, causing a problem when I try to take the substring. I tried adding a char variable that would be read after m and l, which would, supposedly, get the \n. However, it is getting the first letter of the newline instead, which, then, messes up my code. I tried to see if I had any syntax errors or anything, but that isn't it. I also looked for ways to ignore the \n char, but everything I found was related to strings, or reading from files.
I know I could read the line, and then cast the two ints from string to int, but that seems like a bad way to do it (at least it would be a bad way to do it in C).
Anyways, if any one can help me, that would be awesome, thanks!
P.S.: I don't do a check before the substr operation because, by the definition of the problem, the line will have a 3-char operation, a space and then an integer.
A good place to look for tips for common problems like this is your favorite reference:
When used immediately after whitespace-delimited input, e.g. after int n; std::cin >> n;, getline consumes the endline character left on the input stream by operator>>, and returns immediately. A common solution is to ignore all leftover characters on the line of input with cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); before switching to line-oriented input.
From here.
This is related to: cin and getline skipping input But they don't answer the why it happens just the how to fix it.
Why does cin leaves a '\n' in the buffer but just cin.getline takes it?
for example:
cin >> foo;
cin >> bar;//No problem
cin >> baz;//No problem.
But with cin.getline
cin >> foo;
cin.getline(bar,100);//will take the '\n'
So why it doesn't happen with cin but it does with cin.getline?
Because, when you say getline you say you want to get a line... A line is string that ends with \n, the ending is integral part of it.
When you say cin >> something, you want to get precisely something, nothing more. End-line marker is not part of it, so it's not consumed. Unless you would have a special type for line, but there is no such thing in standard library.
While without citations from standard this might be taken as opinion, but this is logic behind it. They have different semantics. There is also another difference getline works as unformatted input, and operator>> works as formatted input. I strongly suggest reading of those links to get the differences. This also says that they are semantically different.
Another answer, better or not is debatable, would be to quote standard, that I am sure says, how getline behaves, and how operator>> behaves for different types, and say, it works like this, because standard says so. This would be good, because the standard absolutely defines how things work and it can do so arbitrarily... And it rarely does explain motivation and logic behind the design.
You are not comparing cin to cin.getline, but rather cin.operator>> and cin.getline, and that is exactly what these functions are defined to do. The answer to the question "why" is "by definition". If you want rationale, I can't give it to you.
cin.getline reads and consumes until a newline \n is entered. cin.operator>> does not consume this newline. The latter performs formatted input, skipping leading whitespace, until the end of the object it was reading (in your case whatever foo is) "stops" (in case foo is an int, when the character isn't a number). A newline is what remains when the number is consumed from the input line. cin.getline reads a line, and consumes the newline by definition.
Make sure to always check for error on each stream operation:
if(cin >> foo)
or
if(std::getline(cin, some_string))
Note I used std::getline instead of the stream's member because this way there's no need for any magic numbers (the 100 in your code).
So this is a problem that I've been having since I started programming (Not that long ago. I still don't know why I started with C++). When I have some integer variables and the user's input defines them, if the user inputs something other than an integer the program freaks out and runs an endless loop of the last command it was given. I don't think sample code is needed but if it is I can make a basic example pretty easily.
If you want to know exactly what your mistake was, then we'd need to see your code, but the usual idiom is like this:
int i;
while (std::cin >> i) {
// do something with the user's input, i
}
if (std::cin.fail()) {
std::cout << "not a number!\n";
}
If failure occurs and you want to get past the invalid input so that the user can try again, first call cin.clear(), then either cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n') to ignore the whole line, or std::string s; std::cin >> s; to ignore a whitespace-separated word.
Beware that because the second case actually constructs the string in memory, the user could input a few gigabytes without a space, and the program will fail. That's usually fine if the input is from a terminal, it's the user's own stupid fault. It might be less fine if the input is from an HTTP request or other untrusted source, so some time in future you might end up worrying about it...
Check this out Guess the number - Infinite loop when bad read
When programming always, and i mean always, validate your input.
Check if the input you get is sane.
What i mean by that if you get something that is supposed to be int check if it is.
Convert it if it is not.
If you get a string check if it is in bounds, meaning is it to long, to short, to whatever.
cin
Would be the Term to Google for in your case.
I need help with Excercise 7 in Chapter 6 of Stephen Pratas "C++ Primer Plus 5th Edition".
The excercise is to write a program that reads input from the user as "words" and count the vowels and consonants or "other symbol" that each word begins with. To stop the program the user must enter A LONE q.
What I think i have figured out:
I only need the program to read the first character of each word since it only counts the beginning characters.
To know that the input is a word the program will detect if a "space" is before the character, To be more precise that first a "space" come and then directly followed by a character/symbol.
Then to detect if it is a alphanumeric character i will use "isalpha()" on the character and use if/if else statements to let the program detect if it is a vowel or a consonant if we assume that isalpha() is true.
If isalpha is false the program will count the symbol as other.
The loop will continue as long as no lone q appears. So I must be able to write word like quiet, quit and so on without the program stopping the loop.
So to my problems:
How to make a loop check for the conditions described above? (a space followed by a character/symbol)
And how do you define a lone q?(I dont mean the "command" define here) and use it as exit condition for the loop.
You can use a local variable to remember the previous character read from input, reading one character at a time.
A lone character is a word of length 1.
The istream operator >> when applied to a string reads a single word.
The istream operator >> when applied to a character reads a single character
std::string word;
std::cin >> word;
char letter;
std::cin >> letter; // read first no white space character.
// Normally all >> operators drop prefix white space before doing their actual work
// Hence the letter above will ignore whitespace characters.
// But you can suspend the dropping for prefix whitespace like this.
std::cin >> std::noskipws >> letter.
There are two possible solutions, but the easiest is just to use
the fact that your definition of "word" is exactly that used by
the >> on a string. So something like:
std::string word
while (src >> word) ...
will result in a word each time.
For other definitions of word, you'll probably have to define
a state machine, with states like inWord, betweenWords and
whatever, and implement the corresponding state transitions.