how to end input multiple lines in console for c++? - c++

In code like the following:
while(getline(cin, line))
{
// do something
}
How can I tell the console to stop accepting input?
This is a link to the full code.

Hitting ctrl+D on Unix-like systems (including Linux), or ctrl+Z on Windows is the standard way to signal "End of input" to command-line programs (traditionally called "EOF" for "end of file"). It will cause std::getline to return a value that will evaluate as false in your while statement, ending the loop and continuing with the rest of your program.

You should add a condition like line == "end" and break out of the while loop if that happens, but if you want to avoid changing the code, Ctrl+D will send an EOF and will tell the terminal to stop accepting inputs.

Related

Receiving input from user in c++

I'm trying to read input from user in this way
std::string point;
while (std::getline(std::cin, point))
{
// SOME CODE
}
I want to receive input from user until he hits CTRL+D which means EOF.
obviously in the current situation I get an error since it doesn't end when I hit CTRL+D. Any tips? Thanks!
In Windows, Ctrl+Z or F6 on an otherwise empty line is the convention for marking end-of-file for a text stream. In Unix-land, Ctrl+D is the convention for sending your typed text straighaway to the program, which for an empty line sends nothing (a zero length input) which the program interprets as end-of-file. Also in Windows the interpretation is in each program, not done by Windows itself or the console subsystem or command shell, and for C and C++ it's handled by the standard library's i/o facilities.
One big difference is that in Windows the Ctrl-Z is data, which you can have in e.g. a text file, while in Unix-land the “submit now!” Ctrl-D is an action, that can't occur in data read from a file.
Another big difference is that because of that, in Windows you have to press Return (Enter, newline) after the Ctrl+Z, while in Unix-land the Ctrl-D is it, on its own.

Why does this while Loop never end?

So I feel that I am close to solving a programming assignment that takes the most used word of each line and prints it on a line. So for example:
I am a man, am right?
I don't know if i like that.
It's okay to not feel okay.
Would print: "am i okay" (punctuations and case are ignored for the assignment)
This is what I have done so far, but the problem is that the while loop that scans the lines never terminates and thus never prints the output in the external for loop. Anybody see where I went wrong?
string line;
vector<string> result;
while(getline(cin,line)){ //on each line
}
Your loop is correct as written; you just don't know how to signify the end of input. You're sitting there waiting for the program to progress, but the program is sitting there waiting for you to give it more input.
Press Ctrl+D (Linux) or Ctrl+Z (Windows) to send the EOF character/signal/potion to end the loop.
This way, all the common shell techniques like file redirection and pipes will also work.
Introducing artificial means like a double-newline or some magic command is non-conventional and makes your program harder to automate. (And making your program magically know that one of the newlines came from a keyboard hit rather than copy/pasting, is just not possible. Nor do you want it to be! That breaks a ton of valuable abstractions.) When writing a command-line tool, stick to standard practices as much as possible.
Currently your program is waiting for an EOF character which indicates the input has ended. If you are running this and entering the input from the command line, you can manually insert an EOF by pressing Ctrl+D on *nix, or Ctrl+Z on windows. This will cause your program to break out of your getline loop.
If you would rather not do that, you need a way to break out of the getline loop, otherwise it will continue to run in that loop.
A nice idea might be detecting an empty line, so pressing enter twice ends the loop:
while(getline(cin,line)){ //on each line
if(line == "")
break;
...
}

How can I flush stdin? (environment: Mingw compiler, running in xterm or mintty of Cygwin)

There are two ways that I know to flush stdin:
(1) bool FlushConsoleInputBuffer(_In_ HANDLE hConsoleInput);
(2) fflush (stdin);
However, in my environment:
Compiler: MinGW g++
Running in: Windows, Cygwin xterm or Cygwin mintty
Neither of them works.
What can I do?
Note: FlushConsoleInputBuffer() works if my program runs under dos prompt window. In addition, FlushConsoleInputBuffer() nicely returns false, when it runs on Cygwin xterm or mintty.
--UPDATE--
I suspect that Cygwin handles stdin separately than Windows native stdin, which make FlushConsoleInputBuffer() fail.
#wallyk: yes. 'flush' means dropping all unread buffered inputs.
--UPDATE-- (final answer accepted and reason)
Tony D is right. The problem is that Cygwin terminal is a unix-like terminal, which allows editing before 'ENTER' key is hit. Thus any partial input must be buffered and will never be passed to stdin before the 'ENTER' key is hit, since it expects editing commands. I guess it should be possible to overcome this by setting terminal to raw mode (not experimented). Yet the editing feature will be lost in the raw mode.
fflush is meant to be used with an output stream. The behavior of fflush(stdin) is undefined. See http://en.cppreference.com/w/cpp/io/c/fflush.
If you use std::cin to access stdin, you can use std::istream::ignore() to ignore the contents of the stream up to a given number of characters or a given character.
Example:
// Ignore the rest of the line.
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Working code: http://ideone.com/Z6zLue
If you are using stdin to access the input stream, you can use the following to ignore the rest of the line.
while ( (c = fgetc(stdin)) != '\n' && c != EOF);
Working code: http://ideone.com/gg0Az2
Discarding exactly and only the data currently buffered/available to stdin isn't supported using only C++ Standard library features.
Most of the time, programmers just ignore (see example at the bottom of that page) the rest of a problematic line then try the next buffered line. If you're concerned there may be a lot of problematic lines - for example, that the user may have cut-and-pasted pages of nonsense that you want to discard, but then you do want to give them a chance to enter further lines, you need to use an OS-specific function to work out when a read on stdin would block. You'd then ignore lines until that would-block condition is true.
select and poll are two such operations that work on most Operating Systems, but from memory they're only defined for socket streams on Windows so of no use to you. Cygwin may or may not support them somehow; if you want to try it - you would ignore lines as long as the stdin file descriptor (which is 0) tests readable. You'll find lots of other Q&A discussing how to see if there's input available: e.g. checking data availability before calling std::getline, Check if stdin is empty, Win32 - read from stdin with timeout
Keep in mind that your terminal program is probably internally buffering what you type until you press ENTER, so at most your program can clear the earlier lines but not a line the user's partially typed (though you could use some heuristic to discard it after it's sent to your program's stdin).
UPDATE
Cruder alternatives that might be good enough in some circumstances:
save the now() time, then loop calling getline(std::cin, my_string) until either it fails (e.g. EOF on stdin) or the time between reads is greater than some threshold - say half a second; that way it's likely to consume the already-buffered but unwanted input, and yet ENTER for further hand-typed user input's likely to happen after the discarding loop's terminated: you could prompt ala std::cout >> "bad input discarded - you may press ^U to clear your input buffer if it contains unwanted text...\n"; (Control-U works for many terminals, but check your own)
have a particular string like say "--reset--" that the user knows they can type to stop discarding lines and switch back to processing future lines

Doing operations in a while loop until a key combination is invoked c++

I have the following issue. I want to do some certain operations in a Linux terminal until the key combination CTRL+D is invoked. I have found a C++ library function for Windows that can do this, but no easy solution for Linux. The code skeleton will be something like this:
while(!invoked){ //Until CTRL+D is pressed
//Do something
}
//Continue when CTRL+D is invoked
Is this possible?
This interrupts the cycle when the combination `CRTL + D' is inserted :
while ((c = getchar()) != EOF)
Note in Linux is CRTL-D stands for EOF. It is the equivalent of CTRL-Z in windows.
the easiest way to wait for Ctrl+D is to read smth from std::cin and then check for EOF in a stream.
the problem is: this call would block. so doing smth should occur in some other thread. then, you have to signal (via conditional variable for example) to that worker thread from the waiter...
Use getch from (n)curses library. As zaufi already explained, checking for EOF while reading from standard input, with, e.g. getchar, is like checking for Ctrl-D, but it's a blocking operation. getch is non-blocking (in nodelay mode), so more suitable for things like, for example, games.

How to terminate a program with Ctrl-D?

I am trying to write a simple program that simulates a calculator. I would like the program to exit or turn-off when the Ctrl+D keystroke is made. I searched through stackoverflow and saw other examples of Ctrl+C or Ctrl+A but the examples are in java and C.
for C:
(scanf("%lf", &var);
for java, a SIGINT is raised when Ctrl+Z is pressed.
signal(SIGINT,leave);
for(;;) getchar();
I am wondering what can I do for Ctrl+D in C++...
Thanks everyone!
Ctrl+D will cause the stdin file descriptor to return end-of-file. Any input-reading function will reflect this, and you can then exit the program when you reach end-of-file. By the way, the C example should work verbatim in C++, though it may not be the most idiomatic C++.
Is this homework, by the way? If so, please be sure to tag it as such.
If you need to terminate with Ctrl-D while reading input.
while ( std::cin ) // Ctrl-D will terminate the loop
{
...
}
You could make life easier and scan for a keyword like "quit" or "exit". Last time I used a calculator, these words were not on the keypad.
Many simple calculator programs read the input as text terminated by a newline. They parse the text in memory, then spit out an answer.
Other more sophisticated calculator programs use windows and are event driven. Some use a button like "=" to signal end of input and start of calculation (doesn't work on RPN calculators).
These techniques remove the hassle of determining End Of Text input using a control character sequence and are more portable.
Under Unix, the terminal will interpret Ctrl+D (on an empty line) as the end of input; further reads from stdin will return EOF, which you can watch for.
Ctrl+D on Unixy platforms is EOF. If you are getting each char, you can check to see if you got EOF.