gets and cin

B

Bartek

Compiler: g++
code:

char data[30];
int e;
//..

gets(data);

// ..

cin >> e;

//..

gets (data);


problem: the second gets() is not working - not asking for data from
keyboard at least. When I delete line with cin it is working. What is
going on and how to improve it.

Thanks for help
 
D

David Fisher

Bartek said:
You can say:

cin.sync_with_stdio()

at the top of your code to make stdin (which gets() uses) work with C++
streams ...

By the way, did you know there is a cin.getline() function ?
Best to avoid mixing stdin and cin in general ...

David F
 
D

Dietmar Kuehl

char data[30];
int e;
gets(data);
cin >> e;
gets (data);
problem: the second gets() is not working - not asking for data from
keyboard at least.

After reading the numeric input ('cin >> e') the stuff following is still
sticking in the input stream. In particular, the "\n" sought by 'gets()'
is still there. Thus, 'gets()' finds an empty line (the stuff following
the integer in the input) and happily finishes.

To avoid this problem, you should probably skip trailing garbage following
the numeric input. What exactly constitutes this garbage is somewhat
dependent on the use. The easiest would be to skip all whitespace following
the numeric input:

std::cin >> e >> std::ws;

This would, however, also skip empty lines, lines made up only of white
space, and leading whitespace. Often it is more desirable to only skip
the stuff up to and including the next newline:

std::cin >> e;
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

BTW: 'gets()' is to be avoided in all cases! It is just present due to
legacy code (and it is legacy in all meanings of the word) which still
uses it. This function is extremely prone to buffer overruns and one of
the biggest offenders when it comes to whatever kind of attack. The
problem with this function is that you cannot pass the maximum size of
the buffer in. You should replace it by 'fgets()' if you want to really
use a C function or, IMO preferably, with 'std::getline()'.
 
C

Chris \( Val \)

| >
| > > Compiler: g++
| > > code:
| > > gets(data);
| > > cin >> e;
| > > gets (data);
| >
| > You can say:
| >
| > cin.sync_with_stdio()
| >
| > at the top of your code to make stdin (which gets() uses) work with C++
| > streams ...
|
| By the way, did you know there is a cin.getline() function ?
| Best to avoid mixing stdin and cin in general ...

Since gets() is a dangerous function, even better would
be to not use it at all :).

Cheers.
Chris Val
 
C

Christoph Rabel

Dietmar said:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

I thought that numeric_limits<int>::max() was the correct term (at least
according to C++98, 27.6.1.3). Has this changed in C++03?

Christoph
 
B

Bartek

Ok, I've changed gets to cin.getline and I've put also ignore which
was still needed in my opinion.
 
D

Dietmar Kuehl

Ok, I've changed gets to cin.getline and I've put also ignore which
was still needed in my opinion.

Note that I didn't recommended 'std::cin.getline()' but rather
'std::getline()' which operates on 'std::string's:

std::string buffer;
std::getline(std::cin, buffer);

This approach allows [nearly] arbitrary length lines.
 

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

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top