User Input: Strings and Numbers [C++]

Please support our C++ advertiser: Intel Parallel Studio Home
1
John A John A is offline Offline | Dec 2nd, 2008
>Not sure if you guys are not considering "fflush" on purpose
Actually, yes... http://www.gidnetwork.com/b-57.html
 
0
V.V.Raman V.V.Raman is offline Offline | Jan 22nd, 2009
My question is regarding he use of numeric_limits<streamsize>::max().
I found that this compiled in the command line using the C++ command in Bloodshed Dev-C++. However, when I tried to compile this code in a console project in Visual C++ 6.0, I was successful only after including headers for <stream> and <limits>. Why this difference?
Raman
 
1
John A John A is offline Offline | Jan 22nd, 2009
>Why this difference?
Well, first of all, Visual C++ 6.0 is a fairly old compiler and doesn't really conform to proper C++ standards. You should really get a newer compiler (Try the Express edition of Visual Studio 2008).

Second, some compilers' headers include other headers, some don't. In this case, because I was using the STL objects string, stringstream, cout, numeric_limits<T>, it means I should have also included the following headers in the code:
  1. #include <string>
  2. #include <limits>
Those headers are included by default from iostream in gcc. But you are correct, I should update the tutorial.
 
0
V.V.Raman V.V.Raman is offline Offline | Jan 26th, 2009
Originally Posted by John A View Post
>Why this difference?
Well, first of all, Visual C++ 6.0 is a fairly old compiler and doesn't really conform to proper C++ standards. You should really get a newer compiler (Try the Express edition of Visual Studio 2008).

Second, some compilers' headers include other headers, some don't. In this case, because I was using the STL objects string, stringstream, cout, numeric_limits<T>, it means I should have also included the following headers in the code:
  1. #include <string>
  2. #include <limits>
Those headers are included by default from iostream in gcc. But you are correct, I should update the tutorial.
Thank you for the explanation, John.
Raman
 
0
bemboysms bemboysms is offline Offline | Jul 29th, 2009
are the codes used in the c++ programming same with the dev-c++ programming, coz im using the latter, and will you give me the list of header files and their use and algorithms, i am a fully first time programmer, thanks
 
0
hiyas hiyas is offline Offline | Oct 8th, 2009
God Bless
 
0
wyujack wyujack is offline Offline | Oct 19th, 2009
Originally Posted by John A View Post
User input/output is a key component in the programs you write, yet most online tutorials just provide a quick-and-dirty method of grabbing data. In other words, it works right up until the point the user does something unexpected.

In this tutorial you will learn how to avoid the common mistakes by doing it properly.

Take this typical method that tutorials use to teach user input:

  1. int number;
  2. cin >> number;
  3. cout << "You typed the number " << number << ".\n";

Now let's say you want the user to enter a string that contains a space in it. Since using cin >> myString won't work (it will only grab the first word and then exit), you decide you need to find a function that will grab a whole line of input.

After some Googling, you decide that getline() is probably the best way to do it. You add it to your existing code, and this is how your entire program looks:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. int main() {
  6.  
  7. int number;
  8. string name;
  9.  
  10. cout << "Please enter a number." << endl;
  11. cin >> number;
  12. cout << "Enter your entire name (first and last)." << endl;
  13. getline(cin, name);
  14.  
  15. cout << "Your full name is " << name
  16. << ", and the number you entered is " << number << endl;
  17. return 0;
  18. }

Now you run it and the program totally skips the getline() statement!

Please enter a number.
5
Enter your entire name (first and last).
Your full name is , and the number you entered is 5
That's rather odd. Let's try using only getline for our input (which means the number will be put into a string instead):
  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. int main() {
  6.  
  7. string number;
  8. string name;
  9.  
  10. cout << "Please enter a number." << endl;
  11. getline(cin, number);
  12. cout << "Enter your entire name (first and last)." << endl;
  13. getline(cin, name);
  14.  
  15. cout << "Your full name is " << name
  16. << ", and the number you entered is " << number << endl;
  17. return 0;
  18. }

The program's output being:

Please enter a number.
5
Enter your entire name (first and last).
 Joe Programmer
Your full name is Joe Programmer, and the number you entered is 5
The problem went away.

You will probably suspect something is up with cin and are right. What's actually happening in the first example is:
  1. You enter something in.
  2. You hit return.
  3. All of this is put into the input buffer (including the newline that results from hitting return).
  4. cin grabs whatever it needs (in this case the number), but leaves the newline behind!
  5. Since getline() only grabs 1 line, all it gets is the newline left behind by cin.

To fix this the best approach, although not that easy for newbies, is to avoid the use of cin until you know what you're doing, and let getline() handle your user input. It not only solves the newline problem, but it also solves a number of other problems induced by using cin.

This is relatively easy for people to do until they get to numbers (which usually can't be read into strings because they need to be manipulated). For this, you can use a stringstream to convert the string back into a number:

  1. #include <iostream>
  2. #include <string>
  3. #include <sstream> // need this for stringstreams!
  4. using namespace std;
  5.  
  6. int main() {
  7.  
  8. int number;
  9. string line;
  10. stringstream stream;
  11.  
  12. cout << "Please enter a number." << endl;
  13. getline(cin, line);
  14.  
  15. stream << line;
  16. stream >> number;
  17. cout << "The number entered was " << number << ".\n";
  18.  
  19. return 0;
  20. }

This outputs:

Please enter a number.
4
The number entered was 4.

You can now see how the operation is nearly identical, except that you are taking an extra step by first putting the input a string, and then putting it into a separate stream before popping it back out in the number.

Finally, you actually can mix cin with getline(), if you know what you are doing. The easiest method is to use cin.ignore(<some large number>, '\n') to clear the input buffer. You could simply hard code a large number, although it's usually better to use a built-in constant. The Standard Template Library provides such a constant, which is found in the <limits> header: numeric_limits<streamsize>::max()

If you were to implement this in your first example, it would work like this:

  1. #include <iostream>
  2. #include <string>
  3. #include <limits>
  4. using namespace std;
  5.  
  6. int main() {
  7.  
  8. int number;
  9. string name;
  10.  
  11. cout << "Please enter a number." << endl;
  12. cin >> number;
  13. cin.ignore(numeric_limits<streamsize>::max(), '\n');
  14. cout << "Enter your entire name (first and last)." << endl;
  15. getline(cin, name);
  16.  
  17. cout << "Your full name is " << name
  18. << ", and the number you entered is " << number << endl;
  19. return 0;
  20. }

And the output would be:

Please enter a number.
3
Enter your entire name (first and last).
Joe Programmer
Your full name is Joe Programmer, and the number you entered is 3

However, this should only be used when absolutely necessary, as this is just a band-aid for the function. It doesn't really fix some of the other problems that come with using it. So perhaps it is best to stick with getline(). Don't do the quick-and-dirty method that online tutorials teach you, because it will eventually come back and bite you in the back of the neck. Flushing the input buffer like mentioned previously is only a last resort for using cin; it's not a good alternative to using getline() to handle your input. A little bit of trouble now using getline() will save you a lot of pain later!

Update: Narue has written a nice tutorial showing how to clear the input buffer and all the problems associated with doing so: How do I flush the input stream?
It's very usefull to me .thank you !
 
-1
chaithanya07 chaithanya07 is offline Offline | Nov 12th, 2009
why do we use scope resolution operator?? explain about it please.....
 
 

Message:


Thread Tools Search this Thread



Tag cloud for C++
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC