Re: how to handle Control-D in getline ?
On Apr 9, 11:25 pm, "Martin M. Pedersen" <traxpla...@gmail.com> wrote:
Martin M. Pedersen wrote:
I have a program where I read a lot of user data. How can I handle the
case where the user press control-d ?
Is it possible to disable control-d or re-open the cin ?
I have made a small example which hopefully shows my problem.
#include <string>
#include <iostream>
int main()
{
std::string command;
while (true) {
getline(std::cin,command);
std::cout << std::cin.eof() << " " << command << std::endl;
}
}
========================
========
tusk@skarbinika:~/programming/jiga/jiga/getinput$ ./getinput
hello world
0 hello world
1
1
1
[...continues, until I kill the program...]
Isn't that what happens anyway? I can't think of many things
that would make true evaluate to false, so the program is
obviously designed to run forever.
Judging from your prompt (and the mention of control D), you're
obviously under Unix, so stty can be used to disable ^D. But
I'm not sure that that's what you want. Normally, ^D on an
empty line is the Unix convention for an end of file; something
like:
while ( getline( std::cin, command ) ) {
std::cout << " " << command << std::endl ;
}
handles that quite well. (Short of using stty, I'm not sure
that you can handle it other than at the beginning of the line.)
Oops. Found the solution myself.
#include <string>
#include <iostream>
int main()
{
std::string command;
while (true) {
getline(std::cin,command);
if (std::cin.eof()==1) {
Be careful here. If the input is redirected from a file, and
that file doesn't end in a newline, you'll throw out all data
from the last newline until the end of file.
std::cin.clear();
std::cin.ignore();
I'm not sure what you're actually ignoring here, are you? In
the usual configuration, ^D never makes it to the process. If
the ^D was at the beginning of a line, this line will read one
character (blocking until it gets it), and then throw it away.
continue;
}
std::cout << std::cin.eof() << " " << command << std::endl;
}
}
I rather doubt that just ignoring ^D is a good idea. More
likely, you're users would want it to be interpreted as an end
of file. And of course, the poor user who redirects input from
a file will get an endless loop in your case. My own solution
would be something along the lines:
while ( getline( std::cin, command ) ) {
process( command ) ;
}
if ( std::cin.gcount() > 0 ) {
generateWarning( "File did not end with newline" ) ;
process( command ) ;
}
(This should also work under Windows, in a console window, with
^Z instead of ^D as the interactive end of file.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34