how to handle Control-D in getline ?

  • Thread starter Martin M. Pedersen
  • Start date
M

Martin M. Pedersen

Hi,
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.


Regards
Martin


#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...]
 
M

Martin M. Pedersen

Martin said:
Hi,
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.


Regards
Martin


#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...]

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) {
std::cin.clear();
std::cin.ignore();
continue;
}
std::cout << std::cin.eof() << " " << command << std::endl;
}
}
 
J

James Kanze

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.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,216
Latest member
topweb3twitterchannels

Latest Threads

Top