为什么我的输出文件开头有一个空行

Why does my output file have an empty line at the start

提问人:Aloysious Kok 提问时间:2/28/2023 更新时间:2/28/2023 访问量:92

问:

我正在尝试将数据输出到 .csv 文件

数据格式应如下所示:

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

但是,文件输出如下:


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

输出数据工作正常,但是每次运行输出函数时,文件开头都会有一个空行。

这是我的输出函数代码,它从用户那里获取输入年份并从天气对象的向量中读取数据,使用其他 3 个函数来计算平均数据,它们被存储为全局变量,然后将它们打印到外部文件中。

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;
        }
    }
}
C++ 文件-IO fstream IOSTREAM ofstream

评论

0赞 JaMiT 2/28/2023
这看起来像是一种可以通过构建最小可重现示例来获得答案的情况。第一步,摆脱用户输入。 跳过年份以外的数据,因为在输出这些数据时,症状已经可见。继续删除部分,直到您拥有仍能重现问题的最小代码。在这一点上,您应该开始想知道为什么“将文件的输出值更改为 2 位小数”以某种方式产生神秘的空行......int year = 2015;
0赞 doctorlove 2/28/2023
这似乎被否决了,因为它归结为一个小错误,但是在流插入的末尾拍打 endl 的模式是一种值得讨论的常见反模式

答:

1赞 john 2/28/2023 #1

你认为他们在这里做什么?endl

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

答:将空行添加到文件的开头。如果您不想要空行,请将其删除。

评论

0赞 Aloysious Kok 2/28/2023
天哪,谢谢,这么小的错误困扰了这么久!
2赞 doctorlove 2/28/2023 #2

设置精度时,要添加新行(并刷新缓冲区):

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

只需设置您需要的内容并避免使用新行:

ofile << fixed << setprecision(1);   

值得指出的是,您每个流插入一个 std::endl,

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

你不需要这样做。有关详细信息,请参阅“std::endl”与“\n”。实际上,它正在添加一个新的行字符,并刷新缓冲区。'\n'

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

您可以在不添加新行的情况下插入内容。每次都会添加许多教程和书籍,但可能不需要。std::endl