C++ 从文件读取 - 跳过了第一行,最后一行重复两次

3

我被分配了一个C++程序任务,需要从输入文件读取整数,计算它们的平方根,然后将其打印到输出(屏幕或指定的输出文件)中。我已经能够完成这个任务,但是我的问题是我的代码跳过了input.txt的第一行,然后重复了input.txt的最后一行。

我的代码如下:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <cmath>

using namespace std;


int main(int argc, char *argv[]) {
    
    /* Check to make sure the correct amount of command line arguments have been supplied (if not, then issue error) */
    if (argc > 3 || argc < 2) {
        cout << "Error: Wrong number of command line arguments: " << argc << endl;
        exit(1);
    }
    
    ifstream input_file;            // Create a read file called input_file
    input_file.open (argv[1]);      // Open the file specified by the command line
    
    /* Check to make sure the input file has been opened correctly (if not, then issue error) */
    if (!input_file.is_open()) {
        cout << "Error: Input File failed to open" << endl;
        exit(1);
    }
    
    stringstream solution;          // Create a string stream to hold the final output before deciding where to send it
    
    /* Read through each line of the input file */
    while (!input_file.eof()) {
        string line_str;
        getline(input_file, line_str);
        
        if (line_str.length()) {
            int a, b, c;            // 3 Integer variables for A, B, and C of the Quadratic Formula
            float x1, x2;           // 2 Float variables for the calculated roots
            float discriminant;     // Float variable to determine if roots are complex or not
            
            input_file >> a >> b >> c;      // Attribute next 3 integers from input file to the 3 integer variables
        
            discriminant = (b*b) - 4*a*c;
            
            /* If discriminant is less than zero, then roots are complex. Otherwise, roots are real and can be calculated */
            if (discriminant < 0) {
                solution << a << "\t" << b << "\t" << c << "\t" << "Complex roots, did not compute" << endl;
            }
            else {
                x1 = ( -b + sqrt(discriminant) ) / (2*a);
                x2 = ( -b - sqrt(discriminant) ) / (2*a);
                solution << a << "\t" << b << "\t" << c << "\t" << fixed << setprecision(4) << x1 << "\t" << x2 << endl;
            }
        }
    }
    
    ofstream output_file(argv[2]);  // Create an output file called output_file
    
    /* Determine whether to output solution to the screen or to a specified output file */
    if (argc < 3) {
        cout << solution.str();
    }
    else {
        /* Check to make sure the output file has been opened correctly (if not, then issue error) */
        if (!output_file.is_open()) {
        cout << "Error: Output File failed to open" << endl;
        exit(1);
        }
        output_file << solution.str();
    }
    
    /* Close files */
    input_file.close();
    output_file.close();
    

    return 0;
}

我的输入文件长这样:

1 2 4
4 5 6
1 7 4
2 19 2
2 12 1
2 4 5
29 0 1
2 9 2 
1 28 0

我的输出文件应该长这样:

1   2   4   complex roots, did not compute
4   5   6   complex roots, did not compute
1   7   4    -0.6277    -6.3723
2   19  2    -0.1065    -9.3935
2   12  1    -0.0845    -5.9155
2   4   5   complex roots, did not compute
29  0   1   complex roots, did not compute
2   9   2    -0.2344    -4.2656
1   28  0     0.0000    -28.0000

但实际上,它看起来像这样:

4   5   6   complex roots, did not compute
1   7   4    -0.6277    -6.3723
2   19  2    -0.1065    -9.3935
2   12  1    -0.0845    -5.9155
2   4   5   complex roots, did not compute
29  0   1   complex roots, did not compute
2   9   2    -0.2344    -4.2656
1   28  0     0.0000    -28.0000
1   28  0     0.0000    -28.0000

有人知道这是为什么吗?非常感谢任何帮助!


我有个问题想问你。没有一位称职的老师会告诉你写 while (!input_file.eof()),所以我的问题是:你有一个糟糕的老师吗?还是你自己写的这段代码并且认为它可以完成你想做的事情?我真的很感兴趣得到答案,因为我们经常看到这种错误。可以说这是所有C++错误中最常见的一种。所以我很想知道为什么会频繁出现这种错误。 - john
1个回答

5
第一行并没有被跳过,它被读入到line_str变量中。
getline(input_file, line_str);

最后一行没有被读取两次。它失败了,但是您没有检查文件抽取是否成功。在使用读入的变量之前,您应始终检查其是否成功读取。

与其这样:

input_file >> a >> b >> c; 

使用

if ( input_file >> a >> b >> c )
{
   // Use the values of a, b, and c.
}
else
{
   // Deal with the error
}

另外,使用

while (!input_file.eof()) {

在循环条件中使用iostream::eof(例如`while(!stream.eof())`)不是一个好的做法。请参考为什么将iostream::eof放在循环条件中被认为是错误的?


我建议更新读取和处理输入文件内容的循环,如下:

int a, b, c;            // 3 Integer variables for A, B, and C of the Quadratic Formula
while ( input_file >> a >> b >> c)
{
   float x1, x2;           // 2 Float variables for the calculated roots
   float discriminant;     // Float variable to determine if roots are complex or not

   discriminant = (b*b) - 4*a*c;

   /* If discriminant is less than zero, then roots are complex. Otherwise, roots are real and can be calculated */
   if (discriminant < 0)
   {
      solution << a << "\t" << b << "\t" << c << "\t" << "Complex roots, did not compute" << endl;
   }
   else
   {
      x1 = ( -b + sqrt(discriminant) ) / (2*a);
      x2 = ( -b - sqrt(discriminant) ) / (2*a);
      solution << a << "\t" << b << "\t" << c << "\t" << fixed << setprecision(4) << x1 << "\t" << x2 << endl;
   }
}

这正是我一直在寻找的,它解决了我的两个问题!非常感谢!我刚开始学习C++编程,对C语言也不熟悉,所以一直很困难。再次感谢,这是一个非常简单的修复,我非常感激! - throwaway_bruh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接