What happens during the process of cin.get()? - c++

The code is as follows, when I enter "101010^Z000", my output becomes "000". Obviously, my input is invalid after it becomes "^Z". However, why can I continue typing after typing "^Z"? According to the code, shouldn't it have jumped out of the loop and ended the program at this time? I'm curious.
int main()
{
const int num = 20;
int a[num];
int i = 0;
while((a[i]=cin.get())!=EOF)
{
a[i] = cin.get();
cout.put(a[i]);
i++;
}
cout << a;
}
like this:
And, after this I keep typing "ssss" and the program still outputs "ss" as if the loop is continuing.

Input is usually buffered. There is nothing in C++ that says it must be buffered but usually it is. What this means is that when your program is waiting for input it waits for a whole line of input. That whole line of input goes into a buffer and subsequent reads take characters from the buffer until it is empty. Then the next read will cause the program to wait again, and again it will wait for a whole line of input to be entered.
If you want unbuffered input then I've afraid there is no way to get that in standard C++. You have to use platform specific functions for that.

Related

Why does my code terminate without explanation?

I'm learning c++ again after having not touched it for the last few years, and I've run into a rather peculiar bug that I can't seem to figure out.
When I run the code below, it will accept 10 inputs as I expect it to, but immediately after the first for loop, the program exits. I have run it ingdbto try and figure out the issue, but it reported that the process 'exited normally'.
I compiled using g++ -std=c++11
#include <iostream>
#include <string>
using namespace std;
int main() {
//User inputs
string input[10];
//Get the inputs
for(int i = 0; i < 10; i++) {
//Get this input
printf("%i> ", i);
getline(cin, input[i]);
}
//The application does not make it to this point
//Collected
printf("Thank you for submitting your data.\n");
//Print inputs
for(int a = 0; a < 10; a++) {
//Show the input
printf("%i> %s\n", a, input[a].c_str());
}
}
Based on what you're describing, it sounds like stdout is not being flushed before the program ends. That's unusual; normally, stdout is automatically set up for line-buffered operation in which case it will be flushed as soon as a newline is encountered.
Your best bet is to follow #NathanOliver's advice and use cout << ... rather than printf. The printf command is a throwback to C, and you're using a C++ compiler and C++ features. In fact, you're not even including the header that's usually required for printf, so I'm a little surprised it even compiles.
FWIW, if you choose to continue using printf maybe try manually flushing stdout at the end like so:
fflush(stdout);
Your application does what is supposed to do:
Application will pause at getline() (10 times) (because getline is blocking execution), then it will do some for loops, print something and end (probably closing console window). If you add something at the end to block execution (such as cin.get(), which waits for enter key press) you will see results (because application won't terminate). If you run your code somewhere where output is not removed after program has ended you will see what was printed.

Getting more lines from input in C++

I need to read lines from standard input, but I dont really know, how many it will be.
I tried to do it with getline() and cin combined with a while loop, but it led to an infinite loop:
string line;
while( getline(cin, string) ){...}
or
string word;
while( cin >> word ){...}
it doesnt stops at the end of the input( the lines are coming at one time, so the user is hitting just one time the Enter key ).
Thanks for your help.
Reading your comments you have a misunderstanding of "end of input".
When you start your program it waits for input from console, and if input is available it reads it. Initially your copy some strings to your console so your program takes this as input. But your program still keeps reading from the console because there was no "end of input". The program is still connected to the console.
You need to signal "end of input" to your program. On Windows you do this by pressing Ctrl+Z. On Linux you need to press Ctrl+D.
Your problem is reading from the console.
As your console does not put an EOF(end of file) when you enter an empty line.
You should try pipeing the input from a file to your program. This should end, when there is no more input.
Otherwise, just check if the string is empty, and break out of the loop, if it is empty.
The way you run your program, your input doesn't end, since the console can always provide more input. Your program behaves correctly, though perhaps not in the way you desire. That's because you have misunderstood your own desires.
What you are looking for is perhaps (but I can't be sure) for the program to end when either the input ends or when the input contains a blank line. This can be coded as follows:
int main()
{
for (std::string line; std::getline(std::cin, line); )
{
if (line.empty())
{
std::cout << "Got blank line, quitting.\n";
return 0;
}
// process line
}
std::cout << "End of input, quitting.\n";
return 0;
}

getline causes infinite loop when redirecting file to standard input

The following code simply echoes the standard input to the standard output. If I run the program like so ./a.out, I can type anything and the program works fine. However, if I run it like this ./a.out < input.txt I get an infinite loop, regardless of the content of input.txt.
#include <iostream>
using namespace std;
int main() {
string input;
while (true) {
cout << "Type your input: ";
getline(cin, input);
cout << input << endl;
}
return 0;
}
What am I doing wrong?
EDIT: To clarify, I expect that after the input from the input file is finished, getline waits for more input from stdin. Instead, it continues to read when nothing is there.
You don't have a terminating condition for your loop: while (true) is an infinite loop in any case - that is, without a break/exit/etc. in the loop body.
I'm guessing that when using your program to echo stdin you end it by pressing Ctrl-C. Run your program using ./a.out, and type Ctrl-D (EOF): you'll also get an infinite loop.
Look over the docs for getline: use the return value to end your loop:
while (getline(cin, input))
Your loop has no terminating condition, be it a break, or right inside the while part. Instead, you probably want this:
while (getline(cin, input))
That will end when the input fails, most likely resulting from having reached EOF.
What you're doing wrong is that you ignore the result of an input operation, in this case getline.
You must never ignore the result of an input operation. It is always a programming error to do so. You cannot know or make assumptions about the state of external data, so you must always check whether an input operation succeeded. If it does not, then it is generally an error to access the purported input variable for reading, so you really need to check every time, and before accessing the result.
In the present case, std::getline returns a reference to the stream object, and you can evaluate the stream as a boolean. It evaluates as true if and only if the extraction succeeded; otherwise, you must not use the result (and presumably stop reading).
All in all, the code should go like this:
for (std::string line; std::getline(std::cin, line); )
{
// use "line"
}

very basic C++ program closes after user input for no particular reason?

I just started learning C++ and I wrote this sample program from the text and when I compile and run it, it just closes after the user inputs any number and presses enter. I'm guessing the answer to this is very obvious so forgive me as newbie here....it's really my first C++ program :P
#include <iostream>
using namespace std;
int main ()
{
int numberOfLanguages;
cout << "Hello Reader.\n"
<< "Welcome to C++.\n"
cout << "How many programming languages have you used? ";
cin >> numberOfLanguages;
if(numberOfLanguages < 1)
cout << "Read the preface. You may prefer.\n"
<< "a more elementary book by the same author.\n";
else
cout << "Enjoy the book.\n";
return 0;
}
Imagine you were designing a model for application execution. You have two choices:
A) When the end of a program is reached it shall terminate.
B) When the end of a program is reached the program shall remain alive in some strange limbo state. It will still retain system resources and will not actually be doing anything, but in order to close the user must terminate it explicitly.
I think anyone would go for option A here, and that is what you are seeing. The end of main is reached and your program exits.
If you would like it to pause at the end take some input from the user, i.e.,
char c;
std::cin >> c;
return 0;
The program closes because there's nothing more for the program to do. It outputs the final statements really really fast and then reaches return 0 which causes it to exit. You'll want to do something there to pause the program.
On Windows, a basic way to do that is system("pause"); (you will need #include <stdlib.h>)
cin.getline is a more standard way to do it.
It closes because the execution reaches return 0; and there is nothing left to do.
If you want the program to wait before closing you could add an something like this:
cout << "Press enter to exit...";
cin >> someVarThatWontBeUsed;
You could also run the program from the command line instead of running the .exe. It will reach end of execution anyway but the prompt will stay open.
Your program ends right after you print out your text. If you want to see anything on the screen you can add a cin right before your return 0 so your program waits for a user response before exiting.
// Wait for user to hit enter
cin >> dummyVar;
return 0;
Either put another read from cin to wait for the user, or open the Command Prompt yourself and run it there.
The program you posted has an error. I was not able to compile what you posted.
cout << "Hello Reader.\n"
<< "Welcome to C++.\n"
is not terminated with a semicolon. I added a semicolon and it compiles and runs as you expect.
Edit: Of course, you have to run the program in a terminal that stays open after the program exits, or use cin to wait for more input, or something like that.
After the user inputs a number, which is saved to numberOfLanguages, it reaches return 0 which returns from the main function and thus the program ends.

Strange stdout behavior in C++

I want my program to display the unix windmill while processing. There's a for loop and in every iteration theres a printf function:
printf("Fetching articles (%c)\r",q);
q is one of the characters in the windmill (-\|/) depending on the iteration number.
The problem is - it seems like in 100 iterations there are only two changes in displayed line, and every iteration takes about one second to complete.
What could be the aouse for this?
Here's the whole loop with only two possible chars for the windmill:
for (int i=0;i<numb_articles;i++) {
memset(file_path,0x0,BUFF_SIZE);
url=article_urls[i];
if (rules->print!=NO_PRINT) {
url=modify_url(url,rules->printout,rules->print);
if (url=="NULL")
continue;
}
get_page(url,file_content);
if (strcmp(rules->save.data(),"NULL")!=0)
if (!check_save(rules->save,file_content,url))
continue;
at_least_one_saved=true;
numb_articles_accepted++;
encoding_list[i]=get_encoding(file_content);
title=get_title(file_content,err_msg);
if (title=="")
continue;
title_list[i]=strdup(title.data());
filename=get_filename(title);
int count=numb_fn_found(filename_list,i,filename.data());
char *tmp = new char[10];
if (count>0) {
sprintf(tmp,"(%d)",count);
filename.insert((size_t)filename.length(),tmp);
}
filename_list[i]=strdup(filename.data());
char q;
if (i%2==0)
q='|';
else q='-';
printf("Fetching articles (%c)\r",q);
ofstream output_file;
sprintf(file_path,TMP_FILE,filename.data());
strncat(file_path,".html",5);
output_file.open(file_path);
output_file << file_content;
output_file.close();
}
Flush the output after writing each line:
printf("Fetching articles (%c)\r",q);
fflush(stdout);
Without doing this, normally stdout is buffered and only dumps its output when a newline is seen, or its internal buffer fills up.
The output (console) is buffered. That is, it only writes the output to the screen when the buffer is full or a newline is written. If you want to output characters one at a time, you will need to call fflush(stdout) explicitly to flush the output buffer.