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

thr*_*ruh 3 c++ io file-io command-line file

我的任务是一个 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;
}

Run Code Online (Sandbox Code Playgroud)

我的输入文件如下所示:

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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

但相反,它看起来像这样:

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
Run Code Online (Sandbox Code Playgroud)

有谁知道为什么会这样?任何帮助是极大的赞赏!

R S*_*ahu 5

第一行没有被跳过。它正在被读入line_str

getline(input_file, line_str);
Run Code Online (Sandbox Code Playgroud)

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

代替

input_file >> a >> b >> c; 
Run Code Online (Sandbox Code Playgroud)

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

此外,使用

while (!input_file.eof()) {

Run Code Online (Sandbox Code Playgroud)

不是个好主意。请参阅为什么 iostream::eof 在循环条件内(即`while (!stream.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;
   }
}
Run Code Online (Sandbox Code Playgroud)