473,394 Members | 1,971 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Loop and Input going wrong...

Nepomuk
3,112 Expert 2GB
Hi!
I'm just learning C++ and found something weird - I have the following program:
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2.  
  3. int main()
  4. {
  5.         std::cout << "Please enter a positive integer: ";
  6.         int n;
  7.         do
  8.         {
  9.                 std::cin >> n;
  10.                 std::cout << "You entered " << n << ".\n";
  11.                 if(n<=0)
  12.                         std::cout << "I said, a positive integer! :-P ";
  13.  
  14.         }  while(n <= 0);
  15.       for(int i=1; i<=n; i++)
  16.         {
  17.                 std::cout << i << ". Some text\n";
  18.         }
  19.         std::cout << "Oh, I almost forgot:\n" << (n+1) << ". More text\n";
  20. }
  21.  
  22.  
Now, it works fine, as long as I enter an integer. But if I enter a letter, it always shows
Expand|Select|Wrap|Line Numbers
  1. You entered 134515049.
or a sligtly different number.
It's the same number for any letter, although that constant number changes sometimes after recompiling. It seems to be related to the amount of characters in my code or something like that.
I tried the following:
Expand|Select|Wrap|Line Numbers
  1. do
  2. {
  3.       // the same as before
  4. }  while(n <= 0 || n >= 134515049);
  5.  
and got an output like this:
Expand|Select|Wrap|Line Numbers
  1. You entered 134515065.
  2. You entered 134515065.
  3. You entered 134515065.
  4. You entered 134515065.
  5. You entered 134515065.
  6. You entered 134515065.
  7. ...
My thought was, that maybe it's reading the endl symbol as well, but I've no idea, what I can do against that.
Actually, I'd like to either avoid the user entering letters or interpret them as their ASCII-number or something like that.
Now, why does it give me these weird numbers and how can I get it to work as it should?

Greetings,
Nepomuk
May 5 '08 #1
5 1820
weaknessforcats
9,208 Expert Mod 8TB
You are using the >> operator. That is the formatted input extraction operator. That means when you >> to an int, there will be an int entered.

If not, the >> fails and the stream is put into a fail state. Now the >> operator first checks the fail state and if the state is fail, the >> operator returns without doing anything. Now it appears all of your >> operators have quit working.

Now you have to a) clear the fail state using cin.clear() and then b) you have to remove the offending data using a means other than the >> operator.

Any time you use cin >> there should be a check:
Expand|Select|Wrap|Line Numbers
  1. cin >> myInt;
  2. if (cin.fail())
  3. {
  4.       //fail state is set
  5.       //take corrective action
  6.       //
  7.       cin.clear();    //clear the fail state
  8.       //
  9.       //add logic here to remove the bad data token}
  10. }
  11.  
If you are just learning C++, don't get fancy with the input. Give th program what ot wants. Later when the program is completely working you can come back and beef up the input edits.
May 5 '08 #2
Nepomuk
3,112 Expert 2GB
You are using the >> operator. That is the formatted input extraction operator. That means when you >> to an int, there will be an int entered.

If not, the >> fails and the stream is put into a fail state. Now the >> operator first checks the fail state and if the state is fail, the >> operator returns without doing anything. Now it appears all of your >> operators have quit working.

Now you have to a) clear the fail state using cin.clear() and then b) you have to remove the offending data using a means other than the >> operator.

Any time you use cin >> there should be a check:
Expand|Select|Wrap|Line Numbers
  1. cin >> myInt;
  2. if (cin.fail())
  3. {
  4.       //fail state is set
  5.       //take corrective action
  6.       //
  7.       cin.clear();    //clear the fail state
  8.       //
  9.       //add logic here to remove the bad data token}
  10. }
  11.  
If you are just learning C++, don't get fancy with the input. Give th program what ot wants. Later when the program is completely working you can come back and beef up the input edits.
OK, thank you. At least I understand, what's happening now.
However, this program isn't supposed to do anything else (it's basically just for learning about the syntax), so it's time to "beef up the input edits"! ^^

I tried what you said as good as I could and (with something I found in a tutorial) got this far:
Expand|Select|Wrap|Line Numbers
  1. do
  2. {
  3.         std::cin >> n;
  4.         std::cout << "You entered " << n << ".\n";
  5.         if(std::cin.fail())
  6.         {
  7.                 std::cout << "Failed\n";
  8.                 std::cin.clear();
  9.                 std::cin.ignore(std::cin.rdbuf()->in_avail()); // Found this somewhere else. Hoped it was you "magic logic", but it didn't work...
  10. //              n = -1;
  11.         }
  12.         if(n<=0)
  13.                 std::cout << "I said, a positive integer! :-P ";
  14. }  while(n <= 0);
  15.  
However, no luck. That way, it does give out Failed, but then it just continues. If however I uncomment the n = -1, it repeats itself without checking the input again, so the >> must still be deactivated.

You said, that ">>" formats the input - would I get unformated data with cin.read(...)? And does "unformated" mean, it would be a String? Or integers? Or something even weirder? :-D

Greetings,
Nepomuk
May 6 '08 #3
weaknessforcats
9,208 Expert Mod 8TB
Formatted input means you know ahead of time what type of data is coming. Like for a disc file of people you know the data is name followed by address followed by city. You may also know the name is 30 bytes, the address 50 bytes and the city is 20 bytes.

The same applies to keyboard input.

Therefore, if you don't know what's coming then you can't use the >> operator.

Instead you use cin.get() and fetch the input one byte at a time and figure out what the heck it is. Or maybe cin.getline() to read an entire text record. This can take a lot of code.

In your example, the cin.clear() does reset the fail date but the cin.ignore() is skipping a lot of bytes. Just skip one byte at a time. Also, do not display your input until it is correct:
Expand|Select|Wrap|Line Numbers
  1. do
  2. {
  3.         std::cin >> n;
  4.                if(std::cin.fail())
  5.         {
  6.                 std::cout << "Failed\n";
  7.                 std::cin.clear();
  8.                 std::cin.ignore();
  9.          }
  10.          else
  11.          {
  12.               if(n<=0)
  13.               {
  14.                 std::cout << "I said, a positive integer! :-P ";
  15.               }
  16.  
  17.          }
  18.         }  while(n <= 0);
  19. std::cout << "You entered " << n << ".\n";
  20.  
May 6 '08 #4
whodgson
542 512MB
When I ran your program it performed as expected. When a letter was entered it translated to the integer 2 in all cases tried. When n was initialised to =1, entry of all letters was read as n=1.
May 7 '08 #5
Nepomuk
3,112 Expert 2GB
Formatted input means you know ahead of time what type of data is coming. Like for a disc file of people you know the data is name followed by address followed by city. You may also know the name is 30 bytes, the address 50 bytes and the city is 20 bytes.

The same applies to keyboard input.

Therefore, if you don't know what's coming then you can't use the >> operator.

Instead you use cin.get() and fetch the input one byte at a time and figure out what the heck it is. Or maybe cin.getline() to read an entire text record. This can take a lot of code.

In your example, the cin.clear() does reset the fail date but the cin.ignore() is skipping a lot of bytes. Just skip one byte at a time. Also, do not display your input until it is correct:
Expand|Select|Wrap|Line Numbers
  1. do
  2. {
  3.         std::cin >> n;
  4.                if(std::cin.fail())
  5.         {
  6.                 std::cout << "Failed\n";
  7.                 std::cin.clear();
  8.                 std::cin.ignore();
  9.          }
  10.          else
  11.          {
  12.               if(n<=0)
  13.               {
  14.                 std::cout << "I said, a positive integer! :-P ";
  15.               }
  16.  
  17.          }
  18.         }  while(n <= 0);
  19. std::cout << "You entered " << n << ".\n";
  20.  
Thanks a lot, now I've finally got it working AND I've learnt about formatted input! :-)

Greetings,
Nepomuk
May 8 '08 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

47
by: Mountain Bikn' Guy | last post by:
Take some standard code such as shown below. It simply loops to add up a series of terms and it produces the correct result. // sum numbers with a loop public int DoSumLooping(int iterations) {...
4
by: LT | last post by:
Good day! I'm trying to read in values from input file (in_file) and add them to another file (out_file) Repeat the same process but opening a different file... I'm trying to use a combination of...
7
by: Francis Bell | last post by:
Hello, I've got a 25 line file with lines of data like this: sp/spinnerbait/AAA Lures/Mad Phil/silver/bass/1/1 The first field is the code that determines what to do. I need to loop through this...
3
by: brett | last post by:
Using DOM in IE, how can I loop through FORMs and access FORM elements in a specific form? For example, www.hotmail.com has about 13 forms. I believe the one displayed is dependent on the URL. If...
8
by: ben | last post by:
i have a bit of code, that works absolutely fine as is, but seems over complicated/long winded. is there anyway to shorten/simplify it? the code is below. description of it: it's like strcpy in...
4
by: Byte | last post by:
The following code will not work for me: x = 1 while x == 1: print 'hello' x = input('What is x now?: ') while x == 2: print 'hello again'
5
by: Alex Pavluck | last post by:
I am trying to write the following code to block up evaluation and prompting for entering new information. However, when I break the loop in one object and then return it does not start at the...
16
by: Jen | last post by:
Hi. I have this problem that I think should be easy but have been struggling with this for days. I have a list based on a recordset from a database. This list consists of records meeting a certain...
18
by: Diogenes | last post by:
Hi All; I, like others, have been frustrated with designing forms that look and flow the same in both IE and Firefox. They simply did not scale the same. I have discovered, to my chagrin,...
3
by: stressedstudent | last post by:
I dont know where I am going wrong so I dont know which part to post, this is what I have, can anyone help me figure out where I am going wrong? THanks for any and all help. // into to c++ //...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.