Проблема с чтением из файла, вызывающая бесконечный цикл - PullRequest
0 голосов
/ 13 сентября 2011

Ладно, с этой программой, над которой я работаю, все в порядке, кроме проблемы.Вот код

#include <iostream>
#include <fstream>

using namespace std;

/*
Function Name: CalculateBinary
CalculateBinary takes a number from the main function and finds its binary form.
*/

void CalculateBinary( long InputNum)
{   
    //Takes InputNum and divides it down to "1" or "0" so that it can be put in binary form.
    if ( InputNum != 1 && InputNum != 0)
        CalculateBinary(InputNum/2);

    // If the number has no remainder it outputs a "0". Otherwise it outputs a "1". 
    if (InputNum % 2 == 0)
        cout << "0";
    else
        cout << "1";
}


void main()
{
    // Where the current number will be stored
      long InputNum;

    //Opens the text file and inputs first number into InputNum. 
    ifstream fin("binin.txt");
    fin >> InputNum;

    // While Input number is not 0 the loop will continue to evaluate, getting a new number each time.
    while (InputNum >= 0)
    {
        if(InputNum > 1000000000)
            cout << "Number too large for this program ....";
        else
            CalculateBinary(InputNum);

        cout << endl;
        fin >> InputNum;        
    }
}

Вот текстовый файл, который я читаю в

12
8764
 2147483648
2
-1

Когда я добираюсь до 8764, он просто продолжает читать это число снова и снова.Он игнорирует 2147483648. Я знаю, что могу решить эту проблему, объявив InputNum как long long.Но я хочу знать, почему он это делает?

Ответы [ 4 ]

4 голосов
/ 13 сентября 2011

Это обычная проблема с такими циклами, которые вы написали.

Правильный и идиоматический цикл такой:

ifstream fin("binin.txt");
long InputNum;
while (fin >> InputNum && InputNum >= 0)
{
   //now construct the logic accordingly!
    if(InputNum > 1000000000)
         cout << "Number too large for this program ....";
    else
         CalculateBinary(InputNum);
    cout << endl;
}
2 голосов
/ 13 сентября 2011

Это число слишком велико для long для хранения, поэтому fin >> InputNum; ничего не делает. Вы всегда должны читать как while(fin >> InputNum) { ... }, так как это немедленно прервет цикл при сбое или, по крайней мере, проверит состояние потока.

0 голосов
/ 13 сентября 2011

Вы не проверяете EOF, таким образом, запертый в цикле навсегда. fin >> InputNum выражение возвращает true в случае успеха, false в противном случае, поэтому изменение кода на что-то вроде этого решит проблему:

while ((fin >> InputNum) && InputNum >= 0)
{
  // ...
}
0 голосов
/ 13 сентября 2011

Может показаться, что тип long на вашей платформе имеет ширину 32 бита.Число 2147483648 (0x80000000) просто слишком велико, чтобы его можно было представить в виде 32-разрядного целого числа со знаком.Вам нужен либо тип без знака (который, очевидно, не будет работать с отрицательными числами), либо 64-разрядное целое число.

Кроме того, следует проверить, успешно ли выполнено чтение:

  ...
  cout << endl;
  if (!(fin >> InputNum)) break; // break or otherwise handle the error condition
}
...