3

I have been tasked with a C++ program in which I need to read integers from an input file, calculate their roots, and then print them to an output (either the screen or a specified output file). I have been able to achieve this, but my problem is that my code is skipping the first line of the input.txt and then repeating the last line of the input.txt

My code is as follows:

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

My input file looks like this:

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

And my output file SHOULD look like this:

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

But instead, it looks like this:

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

Does anyone have any idea why this is happening? Any help is greatly appreciated!

  • Question for you. No competent teacher is going to tell you to write `while (!input_file.eof())`, so my question is, did you have a bad teacher, or did you write that code yourself and simply assume that it does what you want? I'm genuinely interested in the answer, as we see this error all the time. Arguably it's commonest C++ error of all. So I'm interested to know why it's made so frequently. – john Sep 09 '20 at 04:32

1 Answers1

5

The first line is not being skipped. It's being read into line_str in the line

getline(input_file, line_str);

The last line is not being read twice. It is failing but you are not checking whether extraction from the file was successul. You should always check that before using the variables you are reading into.

Instead of

input_file >> a >> b >> c; 

use

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

Also, use of

while (!input_file.eof()) {

is not a good idea. See Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?


I would suggest updating the loop for reading and processing the contents of the input file to:

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;
   }
}
R Sahu
  • 196,807
  • 13
  • 136
  • 247
  • This is EXACTLY what I was looking for, it solved both of my problems! Thank you a million times! I am brand new in C++ coding as I just started a new course, and I was always terrible at C and so it's always been a struggle to me. Thank you again, this was a very simple fix and it was much appreciated! – throwaway_bruh Sep 09 '20 at 05:59