【问题标题】:Problem with reading from file causing infinite loop从文件读取导致无限循环的问题
【发布时间】:2011-11-16 08:43:29
【问题描述】:

好的,我正在处理的这个程序似乎一切正常,除了有问题。这是代码

#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 来解决这个问题。但我想知道为什么会这样?

【问题讨论】:

  • 2147483648之前的空格应该在吗?
  • 根据 binin.txt 的输入,这个程序可能有 UB。
  • @Mystical 是一回事,但我没问清楚我想问什么
  • @Steffan:我知道,所以我没有说“重复”。

标签: c++ loops infinite


【解决方案1】:

您平台上的long 类型似乎是32 位宽。数字 2147483648 (0x80000000) 太大而无法表示为带符号的 32 位整数。您要么需要无符号类型(显然不适用于负数),要么需要 64 位整数。

另外,你应该检查读取是否成功:

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

【讨论】:

    【解决方案2】:

    您不检查 EOF,因此永远被困在循环中。 fin &gt;&gt; InputNum 表达式如果成功则返回true,否则返回false,因此将您的代码更改为类似这样的代码将解决问题:

    while ((fin >> InputNum) && InputNum >= 0)
    {
      // ...
    }
    

    【讨论】:

      【解决方案3】:

      这个数字太大,long 无法存储,所以fin &gt;&gt; InputNum; 什么也不做。您应该始终阅读为while(fin &gt;&gt; InputNum) { ... },因为这将在失败时立即终止循环,或者至少检查流状态。

      【讨论】:

        【解决方案4】:

        这是您编写的此类循环的常见问题。

        正确且惯用的循环是这样的:

        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;
        }
        

        【讨论】:

        • @pezcode:有一个错字。我想用 0 初始化InputNum
        • @Nawaz,只需反转 while 循环条件。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多