Good Afternoon,

I 'm new to C++ programming, and I have to do a program that deals with nested loops. Can anyone please check the code that I have for PART C and PART D of the program. Here is the code of the program.

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <cmath> 
#include <cstdlib>
#include <iomanip>
#include <limits.h>              //changed by sirisha

using namespace std; 

int main( )
{
    //input file objects
    ofstream outFile;           //output file 
    ifstream inFile;            //input file

    //variable declarations
    int number;                 //var to store an int value
    int sum, min, max, avg;     //vars to store simple statistical info
    int counter;                //a counter for controling the loop
    int size;                   //another counter
    int row, col;               //loop variable for rows and columns

    /************************************************************
    Part A. Create a data file data.txt in range of 0 to 9999
    As assume 10 lines, each line with 8 random numbers 
    in the range
    ************************************************************/
    //use two nested for-loops to create the data file 
    //open data.txt
    outFile.open("data.txt"); 

    if (outFile.fail())
    {
        cout<<"failed to open data.txt so break ...... "<<endl; 
        return 1; 
    }
    for (row = 0; row < 10; row++)                       //outer loop for rows/lines
    {
        srand(row);                                     //set random seed

        for (col = 0; col < 8; col++)                    //inner loop for columns/number per row
        {
            outFile <<setw(10)<<right<< rand()%10000; //generate a random number between 0 and 9999
        }
        if (row != 9)                                   //move to next line
            outFile <<endl;                               //but do not move at the last line
    }
    //close outFile
    outFile.close(); 


    /************************************************************
    Part B. Use two nested for-loops to process data.txt
    ************************************************************/
    cout<<" Use two nested while-loops to process data.txt "<<endl; 

    //open data.txt for input
    inFile.open("data.txt");

    for (row = 0; row < 10; row++)           //outer loop to process rows/lines
    {
        //initialization
        sum=counter=max=avg =0;
        min=INT_MAX;                        //min has the maximum integer valued assigned//changed by sirisha                       
        size = 8; 

        for (col = 0; col < 8; col++)        //inner loop to process column/numbers in a row
        {
            inFile>>number;                 //get next number       
            sum += number;          
            if (number > max)
                max = number; 
            if (number < min)
                min = number;
        }

        //show stats for each row
        cout<<" \nStatistical info about row " << row +1 <<" is "<<endl
        <<" \t The sum is " << setw(10)<<right<<sum << endl 
        <<" \t The min is " << setw(10)<<right<<min << endl
        <<" \t The max is " << setw(10)<<right<<max << endl
        <<" \t The Avg is " << setw(10)<<right
        <<setprecision(4)<<fixed<<showpoint
        <<static_cast<double> (sum) / static_cast<double> (size) << endl; 
    } 

    /*******************************************************************
     Part C. This is for you: Re-do Part B with two nested while-loops
     *******************************************************************/
    sum=counter=max=avg =0;
        min=INT_MAX;                                                
        size = 8; 
    cout<<" Use two nested while-loops to process data.txt "<<endl;
    inFile.open("data.txt");

    while(row < 0)
    {
        while(col < 0)
        {
            inFile>>number;
            sum += number;
            if (number > max)
                max = number;
            if (number < min)
                min = number;
        }
    cout<<" \nStatistical info about row " << row +1 <<" is "<<endl
        <<" \t The sum is " << setw(10)<<right<<sum << endl 
        <<" \t The min is " << setw(10)<<right<<min << endl
        <<" \t The max is " << setw(10)<<right<<max << endl
        <<" \t The Avg is " << setw(10)<<right
        <<setprecision(4)<<fixed<<showpoint
        <<static_cast<double> (sum) / static_cast<double> (size) << endl; 
    } 


    /*********************************************************************
     Part D. This is for you: Re-do Part B  with two nested do-while-loops
     *********************************************************************/
    cout<<" Use two nested while-loops to process data.txt "<<endl; 


    inFile.open("data.txt");
    sum=counter=max=avg =0;
        min=INT_MAX;                                                
        size = 8; 
    do
    {
        inFile>>row;
        row += number;
        do
        {
            inFile>>number;                     
            sum += number;          
            if (number > max)
                max = number; 
            if (number < min)
                min = number;
        }while(col < 0);




        cout<<" \nStatistical info about row " << row +1 <<" is "<<endl
        <<" \t The sum is " << setw(10)<<right<<sum << endl 
        <<" \t The min is " << setw(10)<<right<<min << endl
        <<" \t The max is " << setw(10)<<right<<max << endl
        <<" \t The Avg is " << setw(10)<<right
        <<setprecision(4)<<fixed<<showpoint
        <<static_cast<double> (sum) / static_cast<double> (size) << endl; 
    }while(row < 0);

    //well done and exit
    return 0; 
}

Dani AI

Generated

The main problems in the posted Parts C and D are: row/col are never initialized or incremented, the loop conditions are wrong (they test for < 0 so they never run), the file is re-opened without resetting/closing the stream, and the do-while section reads into row instead of using row as a loop index. noticed the reset/negative-condition and file issues, and ’s advice about converting the four parts of a for into explicit initialization, condition, and increment is what you need to apply to nested loops.

A straightforward fix for Part C (nested while) is: reset the input position, initialize row = 0, then for each row reset col = 0 and the stats, read eight numbers inside the inner while, update min/max/sum, increment col, print the stats, then increment row. Example skeleton:

inFile.clear();
inFile.seekg(0);
row = 0;
while (row < 10) {
    col = 0;
    sum = 0; min = INT_MAX; max = INT_MIN;
    while (col < 8) {
        if (!(inFile >> number)) break;   // check read success
        sum += number;
        if (number < min) min = number;
        if (number > max) max = number;
        ++col;
    }
    // compute average as double(sum)/8.0 and print
    ++row;
}
inFile.close();

For Part D use the same logic but with do { ... } while so the body runs at least once. Remember to set row = 0 before the outer do, col = 0 before the inner do, and increment col/row inside the bodies. Also always check inFile >> number result before using the value and call inFile.clear() before seekg() if you hit EOF.

Extra tips: seed rand() once (outside the row loop) using srand(static_cast<unsigned>(time(0))), initialize max = INT_MIN (not 0), compute average as a double, and factor the printing into a helper function to avoid copy/paste as suggested. Add temporary cout debug prints for row and col if you still get unexpected behavior.

Recommended Answers

All 5 Replies

You have numerous problems, including that you do not reset col and row to zero in your while versions and you are not entering the while because you allow only negative row and col values. You are not also closing the file for input.

pyTony,

How would you solve the problem for part C and part D, since I'm just starting to learn C++.

Thank you

I would just do step by step the same things as the for loop does exactly. And I would close the file at end. If you can not do it you have not studied well enough, go through your notes or do some tutorial on loops from net.

You could also add some print statements inside the functioning for version A to understand how the variable values changes, if you do not get it otherwise.

To get the crux of the problem, take another look at what the for() loop does in each of it's four parts. Here is a simplified version of the BNF grammar of the for() expression:

 <for_loop> ::= 'for (' <initialization> ';' <conditional> ';' <increment> ')' <body>

Compare this to the while() loop:

 <while_loop> ::= 'while (' <conditional> ')' <body>

The first part is initialization: it let's you perform an action - usually setting a value, but not necessarily - once, and only once, before the loop is ever run. There's no equivalent to this in the while() loop, so whatever is done in the initialization part of the for() loop has to be done before the while() loop begins.

The second part is the conditional, which tests to see if something is true, and if it is, it runs the loop through once. This is exactly the same as the while() loop's conditional. Therefore, the conditional of the equivalent while() loop should be exactly the same as the conditional part of the for() loop.

The third part of the loop, the increment (or control), runs once per iteration, after the body of the loop has run. It is primarily used to make some change that may alter the value of the conditional - it controls when the loop ends (usually). Again, there is no equivalent in the while() loop, so it has to be added after the end of the body; the difference here is that it must be inside the body, as the last statement of the loop.

The final part of the for() loop is the body, which is the part that is actually being repeated on each iteration. The body of the equivalent while loop should be the same as that of the for() loop, except that the iteration has to be added to it, as said before.

Thus, to take the loop:

for (i = 0; i < 10; i++)
    cout << i << endl;

... and make the equivalent while() loop, you would need to write it as:

i = 0;     // initializer
while (i < 10)
{
    cout << i << endl;
    i++;    // iterator
}

It isn't all that complicated, fortunately, but it can seem confusing at first.

As for closing the input file, you'll want to do this every time you are finished with the file, at the end of the outer loop:

infile.close();

There's another alternative, which is to use after each loop, to reset the file to the beginning each time:

infile.seekg(0, ios:beg);

You would do this instead of re-opening the file each time. This is slightly more efficient, as it doesn't involve repeatedly opening and closing the same file, and is actually a bit simpler as well. However, you would still need to close the file after the last loop.

One last thing: you may want to move the print-out section to a separate function, so that you aren't repeating the same code over and over:

void print_stats(int row, int sum, int min, int max)
{
    cout<<" \nStatistical info about row " << row +1 <<" is "<<endl
        <<" \t The sum is " << setw(10)<<right<<sum << endl 
        <<" \t The min is " << setw(10)<<right<<min << endl
        <<" \t The max is " << setw(10)<<right<<max << endl
        <<" \t The Avg is " << setw(10)<<right
        <<setprecision(4)<<fixed<<showpoint
        <<static_cast<double> (sum) / static_cast<double> (size) << endl; 
}

HTH. C&CW.

Not being really C guy, I am suspicious on the need of include the cmath or even the limits, no, that is needed for INT_MAX, I see.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.