How Ctrl Z works actually - c++

Just for curious mind. During problem solving many question says,"Input will be terminated by Ctrl+z". I know its "EOF(End Of File)" But...
while(scanf("%d",&a)==1)
{ cout<<"OK"<<endl;}
while(scanf("%d",&a)!=EOF)
{cout<<"OK"<<endl;}
while(cin>>a)
{cout<<"OK"<<endl;}
Above 3 will be terminated by Ctrl+z.
while(scanf("%d",&a))
{cout<<"OK"<<endl;}
It will give OK by pressing Ctrl+z.
and
while(1){cin>>a;
cout<<"OK"<<endl;}
Its a infinte loop.
I want to know how Ctrl+z works on a program termination. What is the reason behind it. Please answer in details.

Ctrl+z does not terminate your program. It also doesn't pause its execution. It's a 0x1A byte that is interpreted by iostream and stdio methods to be EOF (end-of-file). After that character is read from the console, nothing is read further and the method that is reading it returns. In the case of iostream, std::ios::eof() becomes true.
You would notice in your last case that if you structured it as:
while(cin >> a) { ... }
It would exit like the others.

Related

How to stop while loop `while(cin>>str){ ... }` which taking string as input? [duplicate]

I have a C program.
int main ()
{
if (getchar()!=EOF)
puts("Got a character");
else
puts("EOF");
}
What should I type into the stdin on the terminal to produce an EOF?
In Windows, Control+Z is the typical keyboard shortcut to mean "end of file", in Linux and Unix it's typically Control+D.
EOF is wrapped in a macro for a reason - you never need to know the value.
From the command-line, when you are running your program you can send EOF to the program with Ctrl-D (Unix) or CTRL-Z (Microsoft).
To determine what the value of EOF is on your platform you can always just print it:
printf ("%i\n", EOF);
You can simulate an EOF with:
Windows: ctrl+Z
Unix: ctrl+D
It's not mentioned in any of the other answers so far, but you may need to press the right key combo (^D or ^Z) 2 or 3 times in order to actually signal EOF; see here for explanation.

When the input will stop?

Hi guys i have the following question:
string s;
std::cout << "give me a string" << std::endl;
while (std::cin >> s){
std::cout << "give me a string" << std::endl;
}
cin.clear();
if s was an integer then i know that if i typed a char then the while would break. If it was an integer and typed a double the same would happened. But what about strings ?? Somewhere I read that in windows (as I am writting at netbeans in windows) you have to press ctrl+z and then it stops as it is taken as a false string. But when i do this , the process freezes and nothing happens.
You need to send the EOF signal, which in Netbeans is Ctrl + D.
However, hitting Enter twice will result in the condition of your loop to resolve in false, causing the loop to stop. That's excpected: How is "std::cin>>value" evaluated in a while loop?
If that doesn't work, use Ctrl + z and a newline character, which is the EOF signal in Windows, as stated here. Ctrl + D is for Linux though, but it works in your case.
The EOF signal closes the input stream, thus breaking the loop.
Moreover, in Netbeans (if the above doesn't work) it seems that you need to run your application from the command prompt to achieve this. Another attempt would be to "press Ctrl + z after pressing Enter", as stated here.
The loop will stop when the input stream is closed.
If you run the program from a shell, then the input stream may be open indefinitely. Exactly how you would close the stream in a terminal, depends on what terminal you are using.
In UNIX, the stream is closed when you send empty input. ctrl + d is the standard key combination for sending (flushing) the input to the stream (^d is the ASCII control code EOT, end of transmission). Pressing enter also sends the input, but it also inserts the end of line character, so it is not possible to use it to send empty input.
ctrl + z is similar in windows, but it has different behaviour (wikipedia):
The EOT character in Unix is different from the Control-Z in DOS. The DOS Control-Z byte is actually sent and/or placed in files to indicate where the text ends. In contrast the Control-D causes the Unix terminal driver to signal the EOF condition, which is not a character, while the byte has no special meaning if actually read or written from a file or terminal.

C++: ctrl+d terminates program (ubuntu)

(New to C++)
I have this simple code (simplified for the question):
int main()
{
string currInput;
while (getline(cin, currInput))
{
}
cout << "wont be printed" << std::flush;
return 0;
}
I have been debugging for a while and I probably miss something:
When running it and pressing ctrl+d (after some strings or right away), it does not print the string that is after the while loop. It just stop running. I thought it might be something with flushing so I added that too.
What am I missing?
PS: When running in debug, it mentions something about sighup signal.
So, with a lot of help from #manni and #rici, we found the problem.
It turns out to be a known problem in cLion.
see sending EOF to stdin in Clion IDE
https://intellij-support.jetbrains.com/hc/en-us/community/posts/206849765-How-to-enter-EOF-Ctrl-z-in-Run-console-
https://youtrack.jetbrains.com/issue/IDEA-12514
Your error is the while loop. You should not be using a loop here. What happens is it hits this line and attempts to get input. Regardless of whether you type in anything or not, if you hit CTRL+D it will end the getline. But you have it in a while loop....so it'll hop back to the top of the loop and get another line...then another line....then another line. Welcome to your first infinite loop.
while (getline(cin, currInput))
{
}
The simplest thing would be to do just
getline(cin, currInput);
If you're starting out programming this is probably what you want to do anyway.
If you feel gutsy, read this page: http://www.cplusplus.com/reference/string/string/getline/
You'll notice that getline returns the stream you pass in. Which will evaluate to true as far the loop is concerned.

C++ Primer 1.4.4 — Importance of EOF and how to write in a code that will end without EOF?

Referring to two questions:
Incorrect output from C++ Primer 1.4.4
Confused by control flow execution in C++ Primer example
My question is answered in both of those posts, but I want to delve further.
First, I know this is only the beginning, but let's say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a EOF? I can't expect someone running my program to know that they need to hit Control-Z.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
Also one guy in those questions somewhat answered the importance of EOF, but how come the program doesn't even post the final cnt - 1?
Let's say I do the numbers 10 10 10 20 20 20. Without EOF, this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
lets say I make a fully functional program that runs in a designed window. By that level, will I already know how to implement a eof? I can't expect someone running my program to know that they need to hit ctrl + z.
You could either tell the user explicitly to do a specific action to end input or the design of the window itself could tell the user the information implicitly. For instance, a dialog box could ask the user to enter input and click an OK button when done.
Is there a way to implement a specific code that functions so that it does not need me to type in an unrecognized value?
It seems like you would rather use a newline character to terminate your input. An example of this usage could be std::getline. Instead of writing
while (std::cin >> val)
you could instead use
std::string line;
if (std::getline(std::cin,line))
and assume that your user's input only consists of one line of values. There are plenty of other ways to similarly achieve this task depending on how you want to constrain the user's input.
Let's say I do the numbers 10 10 10 20 20 20. WIthout eof this will only show the "10 repeats 3 times." How come the program doesn't at least type in the count "10 repeats 3 times and 20 repeats 2 times" minus the final one with white space?
Without the eof your program is still executing the while (std::cin >> val) loop since std::cin >> val has not yet received invalid input.
Since the line
std::cout << currVal << " occurs " << cnt << " times" << std::endl;
occurs after that while loop finishes execution, you don't (yet) see any information about the three 20's in the input.
When you are reading a sequence of inputs you'll need some indication when your down. That could be a sentinel value ("enter 999 to stop reading"; you'd need to detect that while reading), an invalid input ("enter X to stop reading"; when reading an int the value X is illegal and causes the stream to got into failure mode, i.e., have std::ios_base::failbit set), or the more conventional "there isn't anything more to read". For a file, the last conditions is straight forward. When reading data from the console you'll either need to teach people how to terminate the input or you'll need to use a different approach.
If you want to intercept any keypressed and react on them directly you may do so, too. You could, e.g., use ncurses and control your input via that. You could also set the concole to non-buffering (on POSIX systems using tcgetattr() and tcsetattr() to clear the ICANON flag) and deal directly with all key presses to decide whether you want to continue reading or not.
Although I'm certainly up to doing fancy I/O stuff I normally don't bother: users will understand the "end of input" character and just deal with it. That is, my input normally looks something like this:
while (in >> whatever_needs_to_be_read) { ... }
... or, if the input is genuinely line oriented
for (std::string line; std::getline(in, line); ) { ... }
The function doing this input will then be called with a suitable std::istream which may be std::cin although I have typically some way to also read from a file (in addition to the shell-privided input redirection).
BTW, despite some indications in the questions referenced, "EOF" is not a character being read. It is a character entered, though (normally). ... and it is quite conventional to "know" the end of input character (on POSIX systems a ctrl-D and on Windows a ctrl-Z). You can use other indicators, e.g., the "interrupt" (ctrl-C) but that takes more work and doesn't integrate nicely with stream. To use the interrupt chacter you'd need to setup a signal handler for SIGINT and deal with that. One slightly annoying part of doing so is that if you get it wrong you'll need to find a different way to kill the program (e.g. on POSIX using ctrl-Z to put the process to sleep and kill it via a harsher signal).

Getline() Not keeping Application Open?

I'm a first semester C++ student and in class we are building a BMI calculator (Win32 Console Application). I've gotten everything to work just fine, except for one of the instructions, which is wait for user to press enter to close application.
I had success using the system("PAUSE"); statement but in the past I would declare a string variable, like for example, initialize string genVar; and then use getline(cin, genVar); and when the user pressed Enter, the application would close, but it didnt work this time. The application would simply close. It worked just fine with pause, but not with getline().
Is using getline() for this purpose bad practice? Anyone have any clue why it didn't work?
Thank you in advance!
I know this is an old post, but look at the solution which I posted in this question:
C++ Multiple Program Issues (rand, conversion, crashing)
It explains (as chris mentioned in a comment) that getline tends to leave in a new line character in the buffer, which needs to be cleared and reset. Answer above explains it.
std::cin and std::getline do not mix well in general, you usually want to stick to one or the other in a program to avoid input errors and bugs. Your getline probably is grabbing a left over input from as earlier std::cin. I would recommend using this:
std::cout << "Press ENTER to continue...";
std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
return 0;
}
you'll need to include <limits> for this to work correctly.
you can also use the getch() function in the place of std::getline() IMHO