Basic question on integer number input in c++

Mark44

Joined Nov 26, 2007
628
I think its the same as the program you are using (Visual C++, v6.0. )

The program i am using is detailed:

Microsoft Visual Studio 2005
Version 8.0.50727.867 (vsvista.050727-8600)
Microsoft .NET Framework
Version 2.0.50727
Greg, you're using a newer version than I've been using. I'll try your code on Visual Studio 2005, that I also have.
Mark
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Cheers for going to the trouble mark! Though i suspect that you are just as curious as the reason for this as i am :)

Although like i said the same thing occurred on the computers in college which definitely use an older version i think version6.
 

Mark44

Joined Nov 26, 2007
628
I'm really stuck here, since I can't reproduce the behavior you have described. I tried using a different environment and compiler (VS 2005 and VC++ 2005 (v8.0.50727.762)), but I still don't get the infinite loop that you have described. For me to be able to diagnose what's going on, I need to actually see it going on.

The only thing I can think of is to inspect the code that your compiler is generating, looking at the Disassembly window in the debugger. Here's the code that my earlier attempt using VC++ 6.0 produced.
Rich (BB code):
int main()
7:    {
00401010   push        ebp
00401011   mov         ebp,esp
00401013   sub         esp,4Ch
00401016   push        ebx
00401017   push        esi
00401018   push        edi
00401019   lea         edi,[ebp-4Ch]
0040101C   mov         ecx,13h
00401021   mov         eax,0CCCCCCCCh
00401026   rep stos    dword ptr [edi]
8:        cout << "Please enter an even integer value.";
00401028   push        offset string "Please enter an even integer val"... (0042b088)
0040102D   mov         ecx,offset cout (0042ee18)
00401032   call        ostream::operator<< (004015b0)
9:        int number, temp;
10:       float temp2;
11:       do
12:       {
13:           cin  >> temp2;
00401037   lea         eax,[ebp-0Ch]
0040103A   push        eax
0040103B   mov         ecx,offset cin (0042edc8)
00401040   call        istream::operator>> (004010d0)
14:           temp = (int)temp2;
00401045   fld         dword ptr [ebp-0Ch]
00401048   call        __ftol (004044d8)
0040104D   mov         dword ptr [ebp-8],eax
15:           if (temp % 2 == 0)
00401050   mov         ecx,dword ptr [ebp-8]
00401053   and         ecx,80000001h
00401059   jns         main+50h (00401060)
0040105B   dec         ecx
0040105C   or          ecx,0FEh
0040105F   inc         ecx
00401060   test        ecx,ecx
00401062   jne         main+5Ch (0040106c)
16:               number = temp;
00401064   mov         edx,dword ptr [ebp-8]
00401067   mov         dword ptr [ebp-4],edx
17:           else
0040106A   jmp         main+6Bh (0040107b)
18:           cout << "I am sorry but you have to enter an even integer number. Please enter an integer number.";
0040106C   push        offset string "I am sorry but you have to enter"... (0042b01c)
00401071   mov         ecx,offset cout (0042ee18)
00401076   call        ostream::operator<< (004015b0)
19:       }
20:       while (temp%2 !=0);
0040107B   mov         eax,dword ptr [ebp-8]
0040107E   and         eax,80000001h
00401083   jns         main+7Ah (0040108a)
00401085   dec         eax
00401086   or          eax,0FEh
00401089   inc         eax
0040108A   test        eax,eax
0040108C   jne         main+27h (00401037)
21:
22:
23:   return 0;
0040108E   xor         eax,eax
24:   }
If you can capture the same information from your program, I'll take a look at it and see what's happening in your version.

To do this (VC++ 6.0 instructions)
1. Start the debugger running for your program. (In Build menu, Start Debug --> Go)
2. Press F10 one or two times.
3. Open a debugger disassembly window. (View menu, Debug Windows --> Disassembly)
This should show you both your C++ code and the equivalent X86 assembly code that is disassembled from the compiler-generated machine code.
4. Copy everything from the line that says int main() down to the } after the return 0; statement.
5. Paste it into your reply.

Mark
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
Hi mark,
Woah that looks complicated! Thanks for all the effort you are putting into this by the way!

Ok i got the disassembly for you:

--- c:\users\greg\documents\visual studio 2005\projects\temp2\temp2\temp2.cpp --
#include <iostream>
using namespace std;

int main()
{
004114A0 push ebp
004114A1 mov ebp,esp
004114A3 sub esp,0D8h
004114A9 push ebx
004114AA push esi
004114AB push edi
004114AC lea edi,[ebp-0D8h]
004114B2 mov ecx,36h
004114B7 mov eax,0CCCCCCCCh
004114BC rep stos dword ptr es:[edi]
cout << "Please enter an even integer value.";
004114BE push offset string "Please enter an even integer val"... (41786Ch)
004114C3 mov eax,dword ptr [__imp_std::cout (41A338h)]
004114C8 push eax
004114C9 call std::eek:perator<<<std::char_traits<char> > (41114Fh)
004114CE add esp,8
int number, temp;
do
{
cin >> temp;
004114D1 mov esi,esp
004114D3 lea eax,[temp]
004114D6 push eax
004114D7 mov ecx,dword ptr [__imp_std::cin (41A33Ch)]
004114DD call dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::eek:perator>> (41A320h)]
004114E3 cmp esi,esp
004114E5 call @ILT+405(__RTC_CheckEsp) (41119Ah)
if (temp%2 == 0)
004114EA mov eax,dword ptr [temp]
004114ED and eax,80000001h
004114F2 jns main+59h (4114F9h)
004114F4 dec eax
004114F5 or eax,0FFFFFFFEh
004114F8 inc eax
004114F9 test eax,eax
004114FB jne main+65h (411505h)
number = temp;
004114FD mov eax,dword ptr [temp]
00411500 mov dword ptr [number],eax
else
00411503 jmp main+78h (411518h)
cout << "I am sorry but you have to enter an even integer number. Please enter an integer number.";
00411505 push offset string "I am sorry but you have to enter"... (417800h)
0041150A mov eax,dword ptr [__imp_std::cout (41A338h)]
0041150F push eax
00411510 call std::eek:perator<<<std::char_traits<char> > (41114Fh)
00411515 add esp,8
}
while (temp%2 !=0);
00411518 mov eax,dword ptr [temp]
0041151B and eax,80000001h
00411520 jns main+87h (411527h)
00411522 dec eax
00411523 or eax,0FFFFFFFEh
00411526 inc eax
00411527 test eax,eax
00411529 jne main+31h (4114D1h)


return 0;
0041152B xor eax,eax
}
 

Mark44

Joined Nov 26, 2007
628
Greg,
OK, I think we're now in sync. The version above in your previous message is the one without the float variable, temp2. When I run it, and enter a float value, such as 3.2, I now get the infinite loop that you described.

There's one part I don't understand yet, but otherwise, here's what's going on.

Input at first prompt: 3.2<Enter>
temp gets set to 3
temp % 2 != 0, so enter else clause
print "I am sorry etc." on screen
temp % 2 != 0 (still), so start do..while loop again
I'm not given an opportunity to enter anything.
temp is still 3
temp % 2 != 0, so enter else clause
print "I am sorry etc." on screen
temp % 2 !=0 (still), so start do..while loop again
...
ad infinitum

What I think is happening is that when I entered 3.2<Enter> the first pass through the cin >> temp; statement, the characters '3', '.', and '2' were extracted from the input stream, and parsed to convert to an int value. The '3' character was OK, but the '.' couldn't be parsed into an int. My suspicion is that the '.' character never gets consumed, and keeps the loop running until you finally get tired of it, and press CTRL+C.

I'll look into it a bit more to satisfy my "morbid curiosity," as W.C.Fields was wont to say.
Mark
 

Mark44

Joined Nov 26, 2007
628
To put the wraps on this, extraction from cin is failing when you enter an unexpected value. To see this, add the line with the comment inside the do..while loop.
Rich (BB code):
do
{
  cin >> temp;
  bool b = cin.fail(); // added line
  if (temp % 2 == 0)
    number = temp;
  else
    cout << "I am sorry but you have to enter an even integer. Enter an even integer. ";
}
while (temp % 2 != 0);
The first time through the loop, the integer value 3 is extracted from the input stream. You will see that this extraction succeeded, because the b variable will be set to false. This is because cin.fail() returns false, which means that the extraction succeeded; that is, extraction didn't fail. The second time through, however, be gets set be to true, meaning that an int value could not be extracted from the input stream.

That was probably way more than you wanted to know :)
Mark
 

Thread Starter

mentaaal

Joined Oct 17, 2005
451
I can sleep easier now ;-) Cheers mark. Progamming is definitely a tough cookie with all of these quirky things going on. I wouldnt like to imagine having to debug a program with thousands of lines of code!

Shudder
shudder
shudder
 
Top