[HELP] Beginning C++ Question

H

hide2may

Hi There, I'm trying to give some simple math exercises for my kid to
play with but come across the following problem. When the program
comes to "cin >> ans;" it loops forever if the user do not input an
integer (but a char, float, string...whatever). How to solve it,
please?
Thanks in advance, -hide2may

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
char str[80];
int ans=0, count=1;
cout << "What is your name: ";
gets(str);
cout << "Okay " << str << ", let's do some tests.\n";
while( ans != 31*4 ) {
cout << "(" << count << ") 31 x 4 = ";
cin >> ans; // <-------- Here is the question!
cout << "Wrong! Try again /.\\\n";
}
return 0;
}
 
J

Juha Nieminen

hide2may said:
gets(str);

Never use that function. The function gets() was added to the C
standard when the standardization committee was drunk and high, and they
have regretted it since then.

There exists no possible way of using the gets() function safely. It's
simply impossible. If you use gets() from the C standard library, you
*have* a buffer overflow bug in your program, period. There's no way
around it. That function must never be used.

What you should use instead is std::getline().
 
J

Juha Nieminen

Pete said:
Nonsense.

The sentence contained sarcasm, but the point it tries to convey is
completely valid.
Again, nonsense. In most contexts it's now regarded as inappropriate,
but it's been a workhorse, and despite claims that it's inherently
unsafe, there are situations where it can be used safely.

Please go ahead and show me a piece of C or C++ code where std::gets()
is used safely. I'll wait.

The fact is that gets() must never be used, period. Even the linux man
page says that, direct and to the point. If you must use a C library
function to read a string, use std::fgets() instead.
 
V

Verictor

Hi There, I'm trying to give some simple math exercises for my kid to
play with but come across the following problem. When the program
comes to "cin >> ans;" it loops forever if the user do not input an
integer (but a char, float, string...whatever). How to solve it,
please?
Thanks in advance, -hide2may

#include <iostream>
#include <cstdio>
using namespace std;
int main()
{
   char str[80];
   int ans=0, count=1;
   cout << "What is your name: ";
   gets(str);
   cout << "Okay " << str << ", let's do some tests.\n";
   while( ans != 31*4 ) {
         cout << "(" << count << ") 31 x 4 = ";
         cin >> ans;  // <-------- Here is the question!
         cout << "Wrong! Try again /.\\\n";
      }
   return 0;



}- Hide quoted text -

- Show quoted text -

Since ans is defined type of int, so you can't input it as non-int
type. You may want to detect if there is any input errors. For
instance, change the line "cin >> ans" to something like this:

if (!(cin >> ans)) {
cout << "You may have input a non-int number" << endl;
return EXIT_FAILURE;
}

Of course, you can also detect the type too.
 
J

Juha Nieminen

Pete said:
The sentence applies modern standards to criticise decisions made 30
years ago, and then asserts that the people who made the decisions
should have known better. That's at best insulting, and probably libelous.

They should have known better, even 30 years ago. Or are you seriously
telling me that obvious buffer overflow errors were a completely unknown
concept 30 years ago?

Besides, I really *don't* have any problem about insulting the people
who added a monstrosity like gets() to the official language standard.
That shows complete and absolute incompetence. It's one thing to find
that kind of function in some random program out there, a completely
different thing to find it as a *standard library* function which all
standard-conforming compilers must implement. That's just absolutely insane.
Why is the Linux man page the definitive authority on this question?
Doesn't Wikipedia discuss it?

Well, in fact it does: http://en.wikipedia.org/wiki/Gets

Quote: "Use of gets is strongly discouraged. It is left in the C89 and
C99 standards for backward compatibility. Many development tools such as
GNU ld emit warnings when code using gets is linked."

Also: "Safe use of gets requires the programmer to ensure that buffer
overflows cannot be a problem. Standard C provides no way to do this; [...]"
 
J

James Kanze

They should have known better, even 30 years ago. Or are you
seriously telling me that obvious buffer overflow errors were
a completely unknown concept 30 years ago?

gets is goes back to well before 30 years ago. It was certainly
present in Unix version 7 (1979), and probably well before that.

The standards committee standardized it because it was existing
practice, not because they thought it was "good". That's what
standards committees are supposed to do, at least for the first
version of the standard.

As to why the original authors of Unix invented it, as it is,
it's difficult to say. But one shouldn't forget that the
machines they had weren't necessarily connected to any other
machines (no Internet, and not even a LAN), didn't have anywhere
near the memory we have today (I read somewhere---don't know if
it's really accurate---that the first Unix ran on a machine with
12 KB memory.), and were only used by very few people, in a
cooperating environment.

This is not really to excuse the creators of gets---IMHO,
there's really no excuse for it. But the context definitely was
different, and the seriousness of the "error" nowhere near what
it might seem today.
Besides, I really *don't* have any problem about insulting the
people who added a monstrosity like gets() to the official
language standard.

In a certain sense, they had to. It was existing practice, and
that's what standards are supposed to enshrine. Because of
that, every standard has some monstrosities---that were known to
be monstrosities at the time. (There are exceptions, of course:
Ada was created more or less from scratch.)
That shows complete and absolute incompetence.

With regards to the standardization committee, it shows
responsibility, and recognition of their mission. In so far as
possible, existing C code was supposed to be "conform".

[...]

I think you missed the irony. I'd be very surprised if Pete
really considers the Wikipedia a final authority. However...
Quote: "Use of gets is strongly discouraged. It is left in the
C89 and C99 standards for backward compatibility. Many
development tools such as GNU ld emit warnings when code using
gets is linked."

Note the second sentance. The C committee wasn't incompetent;
they were being responsible.
Also: "Safe use of gets requires the programmer to ensure that
buffer overflows cannot be a problem. Standard C provides no
way to do this; [...]"

But some systems might. (Early Unix actually did, if the open
file was a tty.)
 

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,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top