-1

I am trying to output the data to an .csv file

the data format should be like this:

Year
Month,Average WindSpeed(Standard Deviation),Average Temperature(Standard Deviation),Solar Radiation

However the file output is this:


2015
February,21.9(9.5),21.9(9.5),254.7
March,20.2(9.8),20.2(9.8),197.4
April,30.3(4.0),30.3(4.0),0.9

The output data is working fine however everytime i run the output function, there will be an empty line at the start of the file.

This is my function code for the output it gets the input year from the user and read the data from a vector of weather objects, use 3 other functions to calculate the average datas and they are stored as a global variable, then they are being print into an external file.

void FileOutput (Vector<Weather> weatherlog)
{
    int year;
    bool flagWind, flagTemp, flagSolar, flagYear = false;


    cout << "\nAverage wind speed (km/h), average ambient air temperature (sample standard deviation) \nand total solar radiation in kWh/m2 for each month of a specified year: " << endl;
    // get year input from user
    cout << "\nEnter Year (e.g. 2021): ";
    // check input if invalid
    if (!(cin >> year))
    {
        //clear input if invalid
        cin.clear();
        cin.ignore(10000, '\n');
        cout << "Invalid Year" << endl;
    }
    else
    {
        // print year on screen
        cout << '\n' << year << endl;

        // set output file
        ofstream ofile("WindTempSolar.csv");

        // change output values to 2 decimal places for file
        ofile << fixed << setprecision(1) << endl;

        // print year in file
        ofile << year << endl;

        // loop through each month
        for (int month = 0; month < 12; month++)
        {
            //get calculation of average wind speed and stdev
            flagWind = WindCalculation(weatherlog, month, year, &averageWind, &stdevWind);

            //get calculation of average air temperature and stdev
            flagTemp = WindCalculation(weatherlog, month, year, &averageTemp, &stdevTemp);

            //get calculation of solar radiation
            flagSolar = SolarSumCalculation(weatherlog, month, year, &totalSolar);

            if(!flagWind && !flagTemp && !flagSolar)
            {
                continue;
            }

            cout << monthArray[month] << ",";

            if(flagWind == true)
            {
                flagYear = true;
                cout << averageWind << "(" << stdevWind << "),";
                ofile << averageWind << "(" << stdevWind << "),";
            }
            else
            {
                cout << ",";
                ofile << ",";
            }

            if(flagTemp == true)
            {
                flagYear = true;
                cout << averageTemp << "(" << stdevTemp << "),";
                ofile << averageTemp << "(" << stdevTemp << "),";
            }
            else
            {
                cout << ",";
                ofile << ",";
            }

            if(flagSolar == true)
            {
                flagYear = true;
                cout << totalSolar << endl;
                ofile << totalSolar << endl;
            }
            else
            {
                cout << endl;
                ofile << endl;
            }
        }

        // if there is any data in the year, display accordingly
        if (flagYear == true)
        {
            cout << "\nOutput to file 'WindTempSolar.csv': Successful" << endl;
        }
        else
        {
            cout << "No Data, output to file 'WindTempSolar.csv': Successful" << endl;
            ofile << "No Data" << endl;
        }
    }
}
  • This looks like one case where the answer could be obtained by constructing a [mre]. First step, get rid of user input. `int year = 2015;` Skip the data other than the year, since by the time those are output, the symptom is already visible. Keep removing pieces until you have the minimal code that still reproduces the issue. At that point, you should start wondering why "change output values to 2 decimal places for file" somehow produces the mystery blank line... – JaMiT Feb 28 '23 at 10:15
  • This seems to be getting downvoted cos it's down to a small mistake, but the pattern of slapping endl on the end of a stream insertion is a common anti-pattern that's worth talking about – doctorlove Feb 28 '23 at 10:55

2 Answers2

2

You are adding a new line (and flushing the buffer) when you set the precision:

ofile << fixed << setprecision(1) << endl;
//                                   ^--^

Just set up what you need and avoid the new line:

ofile << fixed << setprecision(1);   

It's worth pointing out you have std::endl one each stream insertion,

ofile << [some stuff ...] << std::endl;

You do not need to do that. See "std::endl" vs "\n" for some more details. In effect, it's adding a new line character, '\n' and flushing the buffer.

ofile << [some stuff ...] << '\n' << std::flush;

You can insert stuff without adding a new line. Lots of tutorials and books tend to add std::endl each time, but it might not be needed.

doctorlove
  • 18,872
  • 2
  • 46
  • 62
1

What do you think the endl is doing here?

ofile << fixed << setprecision(1) << endl;

Answer: adding the blank line to the start of your file. Remove it if you don't want the blank line.

john
  • 85,011
  • 4
  • 57
  • 81