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.
Related
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;
...
}
I just noticed this accidentally, with the following code. In the following code,
char teststring[20];
cin.getline(teststring, 20);
the prompt stops for a userinput, and when I press an up arrow, which I did out of muscle memory to check the bash history, it printed the Ansi Escape code (got the details from here) ^[[A and when I pressed a single backspace and pressed enter, the character A got deleted and it printed an un-readable garbage, instead of ^[[, but when I typed the same keys manually or copy-pasted again (to make sure that it is not a similar looking symbol in ASCII) without the last letter, it printed ^[[.
What would be the reason though the characters entered were the same?
The Unix terminal is a very intricate beast. Posix includes a pretty thorough description of its features; the below is just a quick summary.
Normally, the terminal input device operates in "canonical" mode. In that mode, the terminal driver maintains a line buffer which it fills when necessary by reading user input. If the buffer is emptied and more data is requested by the program, the driver will read an entire line of input before providing any more data to the program. So if the buffer is empty, even a getc to read a single character will cause an entire to be read into the terminal driver's buffer before the getc returns.
As the driver reads input characters, it checks for certain special characters; anything else is added to the line buffer and echoed to the terminal device. (Input and output to a terminal device are independent; if the driver or the program didn't echo input, nothing would appear on the screen, which would usually be confusing. Programs turn echoing off in order to be able to accept passwords, for example.)
All of the special characters are configurable. There are quite a few; here are some of the more common ones:
Enter Inserts a newline character into the buffer, and terminates the input line so that the pending read will return.
Ctrl-D (EOF) The character itself is discarded, but the input is terminated and a pending read returns. If the input buffer is empty -- i.e., the Ctrl-D was pressed at the beginning of a line, a zero-length buffer will be returned to the pending read, which will be interpreted as an end of file marker.
Bksp (ERASE) Unless the input buffer is empty, removes the last character from the input buffer and erases it from the screen.
Ctrl-C (INTR) Sends SIGINT to the process.
Ctrl-Z (SUSP) Sends SIGTSTP to the process.
Ctrl-U (KILL) Deletes the entire input buffer.
Ctrl-S (STOP) Stops output.
Ctrl-Q (START) Resumes output if it has been stopped with the STOP character.
When the Linux terminal driver is echoing characters, it will normally echo control characters (characters whose ascii code is less than 0x20) as a caret (^) followed by the character whose code is 0x40 higher, which is usually a letter. The ESC character has the code 0x1B, so it will normally be echoed as a caret followed by the character 0x5B, which is an open square bracket. Hence, you would normally expect ESC to echo as ^[.
Many keys on the keyboard actually send more than one character, and almost all of these sequences start with ESC[. The uparrow, for example, sends the codes ESC[A, and so if you are running a naive program which doesn't handle cursor moving characters, you will see ^[[A echoed when you press the uparrow key.
The character you see is one of the ways used to show characters which don't correspond to any Unicode glyph. The box contains four hex digits, which correspond to the Unicode codepoint, in this case U+001B, which is an ESC character. I don't know why this happened, but it is most likely the result of a race condition between the various components which contribute to the terminal echo.
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
Consider this code:
int a;
cin >> a;
The input doesn't stop when you enter for example 1 or 2; it waits until you press ENTER. How does this work? Why does cin wait for your input until you press ENTER?
Your runtime environment and your terminal control the raw keyboard input. Typically, they only send the input to the application line by line, to allow for editing. You have to speak to your terminal, in a platform-dependent way, if you want it to send you the keyboard input immediately.
(This is often referred to as "raw" mode, as opposed to the usual, line-buffered "cooked" mode. Note that the cooked mode also handles backspace and delete and cursor movement and all that.)
cin just has a buffer behind it that gets filled up with input and then gets emptied as you use the extraction operator (>>). When and how it gets filled up depends on the platform. In Unix-like systems, for example, the input terminal is in either canonical or non-canonical mode. In canonical mode, input is made available line by line. In non-canonical mode, it is available immediately. It's possible to change between these modes (check man termios).
The actual size of the standard input buffer is implementation-defined.
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.