How to compare value in a file with many row ?

I have a file that has 3 columns with many rows. I want to compare the value either increase or decrease for a column. But when I compare, the value always increases even it should be decreased. Any idea how to solve this?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <fstream>
using namespace std;
int main()
    {


    ifstream fromFile;  
    fromFile.open("data.txt");

    {
        cout << "There was an error" << endl;
        exit(1);
    }

    else   
    
        cout << "No error, file opened successfully" << endl;
       
    
        fromFile.clear();
        fromFile.seekg(0);

        for(int i=1; i<=20; i++)
       {        

        int a{}, b {}, c {};
        fromFile >> a >> b >> c ;
       
        cout<<"  Year : " <<a<<" population : "<<b<<" car : "<<c<< endl;

        if ( b < b && c < c )

        cout << " population decrease and car production decrease " << endl;

        if ( b > b && c > c );
         cout << " population increase and car production increase " << endl;
        
        if ( b > b && c < c )

        cout << " population increase but car production decrease " << endl;

        if ( b < b && c > c );
         cout << " population decrease but car production increase " << endl;
        }

    //CLOSES FILES
    fromFile.close();
    return 0;
}



This is my coding to compare the value in the file. But i didn't get the desired output. anyone can help me ?
We need to remember the previous values and compare the current values with the previous values.

Something like this, perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <fstream>

int main()
{
    const char file_name[] = "data.txt" ;

    if( std::ifstream file{file_name} ) // if the file was opened for input
    {
        int year ; // first column
        int last_pop ; // last value of population
        int last_car_prod ; // last value of car production

        // if we could read in the first row
        if( file >> year >> last_pop >> last_car_prod )
        {
            std::cout << "year: " << year << "  population: " << last_pop
                      << "   car production: " << last_car_prod << '\n' ;
            // the values in the first row are the last values for the next row

            int current_pop ; // current value of population
            int current_car_prod ; // current value of car production
            // for every subsequent row in the file, till input fails
            while( file >> year >> current_pop >> current_car_prod )
            {
                std::cout << "year: " << year << "  population: " << current_pop ;

                if( current_pop < last_pop ) std::cout << " (decrease)" ;
                else if( current_pop > last_pop ) std::cout << " (increase)" ;
                else std::cout << " (no change)" ;

                std::cout << "   car production: " << current_car_prod ;
                if( current_car_prod < last_car_prod ) std::cout << " (decrease)\n" ;
                else if( current_car_prod > last_car_prod ) std::cout << " (increase)\n" ;
                else std::cout << " (no change)\n" ;

                // current values become the last values for the next row
                last_pop = current_pop ;
                last_car_prod = current_car_prod ;
            }
        }
        // at end of scope, the file is automagically closed
    }
    else std::cerr << "failed to open file '" << file_name << "'\n" ;
}
Last edited on
Hello Hyung,

Watch your indentation. Not only is what you post poor indentation it does not reflect what it should be.

Your program uses an input file. It is very helpful to include the input file or a good sample, say 10 or 15 records so that everyone will be using the same information. It also helps if you show the output of the program and what the program should be outputting.

I find it helpful to understand what is wrong with your original program before you see any different versions of what you could do.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#include <iostream>

#include <fstream>

using namespace std;  // <--- Best not to use.

int main()
{
    ifstream fromFile("data.txt");

    //fromFile.open("data.txt");

    // <--- Needs an "if" statement.
    {
        cout << "There was an error" << endl;
        return 1; //exit(1);
        // OR
        //return std::cout << "\n     There was an error with opening file \"data.txt\"" << '\n', 1;
    }

    else  // <--- Error. No if statement.

    cout << "No error, file opened successfully" << endl;  // <--- Not part of the else because of the error.

    //fromFile.clear();   // <--- These lines not necessary here. By this point the file stream is open and ready to use.
    //fromFile.seekg(0);  // <--- File pointer is already at the beginning.

    for (int i = 1; i <= 20; i++)
    {
        int a{}, b{}, c{};

        fromFile >> a >> b >> c;

        cout << "  Year : " << a << " population : " << b << " car : " << c << endl;

        if (b < b && c < c)

            cout << " population decrease and car production decrease " << endl;

        if (b > b && c > c);
        cout << " population increase and car production increase " << endl;

        if (b > b && c < c)

            cout << " population increase but car production decrease " << endl;

        if (b < b && c > c);
        cout << " population decrease but car production increase " << endl;
    }

    //CLOSES FILES
    fromFile.close();  // <--- Not required as the dtor will close the file when the function looses scope.
    return 0;
}

Do not use "exit()". This is a C function that causes an immediate termination of the program and does not know anything about C++ classes or to clean up anything about cleaning up a C++ program. Since everything is in 1 file use "return 1" to end the program.

Lines 14 - 19 would execute if the error on line 21 was not a problem.

You say the file has many lines, but your for loop will only run 20 times. So if the file contains less than 20 records the for loop will continue and you would end up with bad information when the loop tries to read the file and can not.

If there are more than 20 records in the file you will be missing information that you will not read.

To use a for loop try: for (; fromFile >> a >> b >> c;). This way it will stop when the "eof" bit is set.

Your if statements do not work because you are comparing "b" and "c" with it's-self thus making each if statement false because "b" and "b" have the same value.

Look at what JLBorges did for ideas.

Line 52 above is not required, but it will not be any problem if you leave it.

This is an idea based on what you started with along with input from JLBorges's program. It is an idea that you could start with.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <iostream>
#include <string>

#include <fstream>

using namespace std;  // <--- Best not to use.

int main()
{
    const std::string inFileName{ "data.txt" };  // <--- Put File name here.

    std::ifstream inFile(inFileName);

    if (!inFile)
    {
        //return std::cout << "\n\n     File " << std::quoted(inFileName) << " did not open.\n", 1;  // <--- Requires header file "<iomanip>".
        return std::cerr << "\n\n     File \"" << inFileName << "\" did not open.\n", 1;
    }

    int year{}; // first column  // <--- ALWAYS initialize all your variables.
    int lastPop{}; // last value of population
    int lastCarProd{}; // last value of car production
    int currentPop{}; // current value of population
    int currentCarProd{}; // current value of car production

    std::cout << "\nYear Population Cars\n" << std::string(20, '-') << '\n';

    if (inFile >> year >> lastPop >> lastCarProd)
    {
        std::cout << year << "   " << lastPop << "    " << lastCarProd << '\n';
    }
    else
    {
        std::cerr << "\n     Failed in reading file\"" << inFileName << "\"\n";

        return 2;
    }

    for (; inFile >> year >> currentPop >> currentCarProd;)
    {
        std::cout << year << "   " << currentPop << "    " << currentCarProd << '\n';
    }

    return 0;  // <--- Not required, but makes a good break point for testing.
}

And it produces this output:

Year Population Cars
--------------------
2015   20000    5000
2016   21000    6000


A nicer way to format the output is to use "setw()" from the "<iomanip>" header file. That way all the numbers would line properly in each row.

Andy
Topic archived. No new replies allowed.