consuming the /n character

Hi guys I was trying to solve a problem for another user and I ended up running into a problem myself haha

the problem is with cin when I try to enter a word to search for it skips the input and it goes straight to the else statement,I thought by using cin.get(), it would have consumed the /n but it didn't,

so question is how come this is happening and how to solve it?


** note breaking this into functions or even a function would have been better practice but just trying to get the code working well get it to do what I want

thanks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 #include <iostream>
#include <vector>
using namespace std;

int main() {

	string word;
	vector<string> words;

	cout << "press ctrl + Z to exit" << endl;

	while (cin >> word) {

		words.push_back(word);

	}
	cout << "enter word you want to find" << endl;
	cin.get(); // thought this would consume the /n solving my problem? but nope
	string wordEntered;
	cin >> wordEntered;

	for (int i = 0; i < words.size(); i++) {

		if (wordEntered == words[i]) {

			cout << "the word is in position " + i << endl;
		} else {

			cout << "word not found " << endl;
		}
	}
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
#include <string>
#include <iostream>

int main()
{
    // ...
    std::cout << "enter word you want to find" << std::endl;
    std::string wordEntered;
    std::getline(cin, wordEntered);
    // ...
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <vector>
using namespace std;

int main() {

	string word;
	vector<string> words;

	cout << "press ctrl + Z to exit" << endl;

	while (cin >> word) {

		words.push_back(word);

	}
	cout << "enter word you want to find" << endl;
	 // thought this would consume the /n solving my problem? but nope
	string wordEntered;
	getline(cin,wordEntered);

	for (int i = 0; i < words.size(); i++) {

		if (wordEntered == words[i]) {

			cout << "the word is in position " + i << endl;
		} else {

			cout << "word not found " << endl;
		}
	}
}


that didn't seem to work,still skipping the input
Last edited on
CTRL-Z is the EOF marker on planet Microsoft. Your stream thinks it's reached the end of file.

In a POSIX shell, it backgrounds the task.
Last edited on
so by pressing CTRL-Z it closes the stream?

also how can you avoid this?

thanks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

#include <iostream>
#include <vector>
using namespace std;

int main() {

	string word;
	vector<string> words;
	bool quit = false;

	cout << "press ctrl + Z to exit" << endl;

	while (getline(cin,word) && !quit) {

		words.push_back(word);
		if(word == "q"){
			quit = true;
		}

	}
	cout << "enter word you want to find" << endl;
    cin.get();
	// thought this would consume the /n solving my problem? but nope
	string wordEntered;
	getline(cin,wordEntered);

	for (int i = 0; i < words.size(); i++) {

		if (wordEntered == words[i]) {

			cout << "the word is in position " + i << endl;
		} else {

			cout << "word not found " << endl;
		}
	}
}



I tried adding a boolean and seems to work better but now when I try to search for the word even if the word is entered it tells me that the word is not found,

I have no idea why it does this when the word clearly has been pushed on the vector

also I have to enter q twice for the while loop to terminate?

hey
hi
hello
q
q
enter word you want to find
hello
word not found
word not found
word not found
word not found
Last edited on
You could try printing wordEntered and each word[i] to be clear on what the program is seeing.
@kbw

thanks for the help I tried debugging like you said and found out that the first letter is been stripped from wordEntered I'm not sure why?

also I'm not sure why after I enter q I still have to enter another word to quit,I'm sure I could add a break; to break out of the loop but I don't want to break out of the loop like that,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <vector>
using namespace std;

int main() {

	string word;
	vector<string> words;
	bool quit = false;

	cout << "press ctrl + Z to exit" << endl;

	while (getline(cin,word) && !quit) {

		words.push_back(word);
		if(word == "q"){
			quit = true;
		}

	}
	cout << "enter word you want to find" << endl;
    cin.get();// thought this would consume the /n solving my problem? but nope
	string wordEntered;
	getline(cin,wordEntered);

	for (int i = 0; i < words.size(); i++) {

		cout << words[i] << endl;;
		cout << wordEntered;
		if (wordEntered == words[i]) {


			cout << "the word is in position " << i+1 << endl;
			break;
		} else {
			cout << "word not found " << endl;
		}
	}
}


here is the output

press ctrl + Z to exit
hi
bye
q
q
enter word you want to find
hi
hi
iword not found
bye
iword not found
q
iword not found
Last edited on
ok so I'm guessing cin.get() consumed the first character of my string,I tried entering cin.get() twice and it did indeed consume two characters of my string,but the question is how is this possible because my cin.get() is called before getline(cin,wordEntered)??

cin is not an object its a function so how is it that the characters get stripped off before I even enter the string for wordEntered?

also I thought cin.get() consumes everything in the buffer up to and including the newline?



thanks
Last edited on
still haven't figured it out =(
so by pressing CTRL-Z it closes the stream?

No, the stream is still open, the stream will now be in an error state. You need to clear() the stream error flags before you try to do anything else.

By the way "CTRL-Z" must be entered as the first characters in the entry.

1
2
3
4
5
	while (getline(cin,word) && !quit) {

		words.push_back(word);
		if(word == "q"){
			quit = true;

You would probably be better off checking for the character 'q' is the first letter of the word and it wouldn't hurt if you told the user to enter 'q' to signal the end of input. You probably don't want to add this "word" to your vector so you should rework your logic to avoid pushing this "word" into your vector.



hi jlb thanks for the reply =)

I kind of came up with a solution but it needs work on

note that I still have some debugging code in there and that the else statement gets run more than once so I need to fix this

also sorry for my spelling and grammar in the codes comment I'm stuck for time,

anyway if you could tell me if I am right in explaining what is happening in my codes comment or if I'm wrong or on the right track,please correct me if I'm wrong,

thanks


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <vector>
using namespace std;

int main() {

	string word;
	vector<string> words;
	bool quit = false;

	cout << "press ctrl + Z to exit" << endl;

	while (cin >> word && !quit) {
		if(word == "q"){
			cin.get();
			/*/
			/  cin will keep getting input from the user until the user enters q
			 * each word that is followed by a blank space is a seperate token
			 * so if user entered one two three three items will be in the buffer
			 * and the while loop will consume three the strings but if this
			 * wasent in a while loop two and three would be left in teh buffer
			 * and only one would be put into the string word
			 *
			 * cin >> does not consume the /n so that means when the while loop
			 * exits when we press quit  the /n will still be in the buffer
			 * so the /n  would be taken by getline(cin,wordEntered)
			 * so wordEntered would be a blank or empty string
			 * to prevent this before breaking from the loop I call cin.get()
			 * this consumes the /n character and program flow works as expected
			 * alternativly we could have used getline(cin,word) by default
			 * getline gets everything entered in(the whole line) and
			 * also consumes the /n character but since we are using single strings
			 * it may be better to use cin >> in this example
			 */

			break;
		}
		words.push_back(word);

	}
	cout << "enter word you want to find" << endl;

	string wordEntered;
	getline(cin,wordEntered);

	for (int i = 0; i < words.size(); i++) {

		cout << words[i] << endl;
		cout << "word entered" << wordEntered << endl;
		if (wordEntered == words[i]) {

			cout << "the word is in position " << i+1 << endl;
			break;
		} else {
			cout << "word not found " << endl;
		}
	}
}
You need to decide whether you want to end the input by using CTRL-Z or 'q'. Trying to use both will probably only confuse you.

/ cin will keep getting input from the user until the user enters q
* each word that is followed by a blank space is a seperate token
* so if user entered one two three three items will be in the buffer
* and the while loop will consume three the strings but if this
* wasent in a while loop two and three would be left in teh buffer
* and only one would be put into the string word


What exactly do you mean by a blank space? If the user enters multiple words before terminating the input with the end of line character ('\n') each word preceding the termination word would be added to your vector. If any words or characters are following the termination word they will be left in the input buffer. So if the user entered "Hello there q big fellow\n" (note only one end of line character), your vector would contain the words "Hello" and "there", "q" would be extracted and discarded, however " big fellow\n" would still remain in the input buffer. You would need to extract all of the remaining characters including the trailing new line character unless you want to use those characters later in your program.

If your user enters "Hello\n", "there\n", "q\n", the you would only have the end of line character to deal with so a single get() may work.


* cin >> does not consume the /n so that means when the while loop
* exits when we press quit the /n will still be in the buffer
* so the /n would be taken by getline(cin,wordEntered)
* so wordEntered would be a blank or empty string
* to prevent this before breaking from the loop I call cin.get()
* this consumes the /n character and program flow works as expected
* alternativly we could have used getline(cin,word) by default
* getline gets everything entered in(the whole line) and
* also consumes the /n character but since we are using single strings
* it may be better to use cin >> in this example
*/

It is true that the extraction operator leaves the end of line character in the buffer.

It is also true that by default getline() will get an entire line, but it can be used to retrieve a single word by using the optional third parameter (the delimiter).

Last edited on
amazing answer jlb,

that makes sense =) I meant whitespace as in if you enter hello there with a single cin >> for example

string hello;
cin >> hello;

and I entered hello there only hello would be entered into the string hello and the rest would be left in the buffer,


thanks =)
your vector would contain the words "Hello" and "there", "q" would be extracted and discarded, however " big fellow\n" would still remain in the input buffer. You would need to extract all of the remaining characters including the trailing new line character unless you want to use those characters later in your program.


how would we solve this problem?

since we couldn't use cin.get() as this would just consume one character we would need to consume the rest of the line would we use getline()?(well it would work but we would have to enter the first discarded word and then the word we want to find and how would the user know which is which,)


for example

1
2
3
4
5
6
7
8

cout << "enter word you want to find" << endl;

	string discard;
	getline(cin,discard);
	string wordEntered;
	getline(cin,wordEntered);



this works for the following input hello there q big fellow /n

but this will only work in that case,if we entered hello there big fellow q /n

our code is broken and does not work the way we want it to work

thanks
Last edited on
The easiest way would be to use getline() to get the entire line, then use a stringstream to process the line to break the line into words. When processing the line if you encounter the word "q" stop processing the line and terminate the loop.

Topic archived. No new replies allowed.