为什么要计算两次的最后一个数字?

时间:2010-07-01 21:05:42

标签: c++

我的程序正在从文件中读取数字 - 它会读取最后一个数字两次。我的程序有什么问题,我该怎么做才能解决它?

int main()
{

    ifstream inputFile;

    int number = 0; //the input for the numbers in the file
    double total = 0; //the total of the numbers
    double counter = 0;//number of numbers
    double average = 0;//average of the number



    inputFile.open("random.txt");//open file
    if (!inputFile)//test for file open errors
    {
        cout<<"Error \n";
    }



    while (inputFile)
     {
        inputFile >> number ;
        total+=number;
        counter++;
        cout<<"The running total is: " <<total <<"\n";

     }


    total=total*1.00;
    counter=counter*1.00;

    average = total/counter;
    cout<<"\nthe final total is: \t" <<total;
    cout<<"\nthe number of numbers is: \t";
    cout<<counter;
    cout<<"\nthe average of the numbers is: \t";

    cout<<setprecision(8)<< fixed<< average<<"\n";

    inputFile.close();
    return 0;
}

文件内容: 42 468 335 501 170 725 479 359 963 465 706 146 282 828 962 492 996 943 828 437 392 605 903 154 293 383 422 717 719 896 448 727 772 539 870 913 668 300 36 895 704 812 323 334 674 665 142 712 254 869 548 645 663 758 38 860 724 742 530 779 317 36 191 843 289 107 41 943 265 649 447 806 891 730 371 351 7 102 394 549 630 624 85 955 757 841 967 377 932 309 945 440 627 324 538 539 119 83 930 542 834 116 640 659 705 931 978 307 674 387 22 746 925 73 271 830 778 574 98 513 987 291 162 637 356 768 656 575 32 53 351 151 942 725 967 431 108 192 8 338 458 288 754 384 946 910 210 759 222 589 423 947 507 31 414 169 901 592 763 656 411 360 625 538 549 484 596 42 603 351 292 837 375 21 597 22 349 200 669 485 282 735 54 1000 419 939 901 789 128 468 729 894 649 484 808 422 311 618 814 515

4 个答案:

答案 0 :(得分:7)

这行代码在到达文件末尾时失败:

inputFile >> number;

但是您的代码在while循环开始之前不检查流是否仍然有效。

尝试:

while(inputFile >> number)
{
    total+=number;
    counter++;
    cout<<"The running total is: " <<total <<"\n";
}

答案 1 :(得分:7)

因为在读取尝试失败后,inputFile变为false 1 ,而在没有更多数据要读取时则不然。因此,当您成功读取最后一个元素时,inputFile仍会计算为true,并启动while的下一次迭代。现在,在inputFile&gt;&gt;数字处设置了failbit,但是你没有立即检查它,所以你的代码正常运行,“思考”另一个元素已被读取(实际上只是旧的一个元素,它仍然存在在number)。

快速解决方案:在阅读后移动支票:

for(;;)
{
    inputFile >> number;
    if(!inputFile)
        break;
    total+=number;
    counter++;
    cout<<"The running total is: " <<total <<"\n";
}

或(更好):

while(inputFile >> number)
{
    total+=number;
    counter++;
    cout<<"The running total is: " <<total <<"\n";
}

这是因为运营商&gt;&gt;返回流对象,该对象在while条件部分中读取之后立即计算。

<小时/> 1.我知道,我知道它实际上并不是假的,但它是操作符(void *)......但不要过于复杂化:)

答案 2 :(得分:2)

我怀疑输入文件(在while行中)的布尔测试只有在实际读取了eof时才会失败。因此,循环将执行一次太多而数字仍将具有旧值,因此将被添加两次。

有关如何编写更好的while循环以读取文件的示例,请参阅http://www.cppreference.com/wiki/io/eof。你可以这样做:

while (inputFile >> number)
   {
   total+=number;
   counter++;
   cout<<"The running total is: " <<total <<"\n";
   }

答案 3 :(得分:1)

你已经获得了一种方法。这是另一种可能性:

int main() {
    std::ifstream inputFile("random.txt");
    std::vector<int> data;

    std::copy(std::istream_iterator<int>(inputFile),
              std::istream_iterator<int>(),
              std::back_inserter(data));

    double total = (double)std::accumulate(data.begin(), data.end(), 0);
    std::cout << "The final total is: " << total << "\n";
    std::cout << "The number of numbers is: " << data.size() << "\n";
    std::cout << "The average is: " << total / data.size() << "\n";
    return 0;
}

这会产生稍微不同的输出(即减去“运行总计”),但我猜你只是添加了它以进行调试。