【问题标题】:C++: How can I output data as CSV to a specific set of cells in an existing file?C++:如何将数据作为 CSV 输出到现有文件中的一组特定单元格?
【发布时间】:2023-06-18 03:38:02
【问题描述】:

所以我循环数据文件以便根据每个数据文件进行计算(计算是针对每个文件中的 20 个 bin 完成的,因此每个文件有 20 个结果)。然后,我想将每个计算放入一个 csv 文件中,以便能够对每个文件的计算进行平均。

每次循环文件时,我都会在单元格 A1 到 A20 中获得一个包含 20 个结果的 csv 文件。

但是,我想要的是一个 csv 文件,其中 20 个结果在单元格 A1 到 A20 中,另外 20 个结果在单元格 B1 到 B20 中等等。最多 20 个结果在单元格 CV1 到 CV20 中。

我在每个循环中的代码输出数据如下所示:

ofstream ofs (path2 + "tanShears.csv", ofstream::out);
for (int j = 0; j < r.size(); j++) {
    ofs << tShears[j] << endl;

显然,当我这样做时,我只会在单元格 A1 到 A20 中得到 20 个结果,这些结果对应于循环中的最终数据集,因为每个循环只会覆盖前一个循环。

有什么想法可以针对 csv 文件中的特定单元格,以便我可以将每个循环的结果输出到同一个 csv 文件的不同部分?

【问题讨论】:

  • 将整个文件读入vector的vector,改变你需要改变的部分,然后把整个写回去。
  • 或者,不要一直关闭并重新打开输出文件。在外循环开始时打开一次,遍历所有数据文件,然后关闭它。
  • 不要每次都打开ofstream,打开一次,连续写入

标签: c++ csv ofstream


【解决方案1】:

CSV 文件的结构如下:

[A1];[B1];[C1];...\n
[A2];[B2];...\n
[A3];[B3];...\n

如果您不想一次写入整个数据,则必须读取整个文件,对其进行解析,进行相应的更改,然后再写入。我会不惜一切代价避免这种情况。

现在来看一些示例代码:(我假设您正在打印一些 int 值)

void writeToCSV(std::vector<std::vector<int>> const& tShears)
{
    ofstream ofs (path2 + "tanShears.csv", ofstream::out);
    for (std::vector<std::vector<int>>::iterator j = tShears.begin(); 
         j != tShears.end(); j++) 
    {
        for(std::vector<int>::iterator i = j->begin(); i < j->end(); j++)
        {
            ofs << i << ";";
        }
        ofs << std::endl;
    }
    ofs.close();
}

在此示例中,内部向量包含您进行的所有计算的第 n 个值。所以它可能包含 A1、B1、C1...

【讨论】:

  • 好吧,这看起来不错。那么我是否会 - 在我的数据文件循环中 - 只需包含函数“writeToCSV(tShears);” (tShears 是我在每个循环中得到的最后一个 20 元素向量)??
  • 在我的示例中,tShears 是一个包含整数值向量的向量。您应该只在数据文件的循环中使用向量。完成循环后,调用 writeToCSV 函数。
【解决方案2】:

您可以将结果保存在一个向量中(一个接一个的 20 个块,或者使用不同的向量)。

然后一次写入所有数据。 csv 第一行中每个块的第一个值,然后是第二个,依此类推。

【讨论】:

    【解决方案3】:

    我是否正确理解了您的问题?
    您有 20 个带有 csv 数据的数据源,每个数据源有 20 个结果。并且您需要对这些数据进行操作,然后将每个数据集写入文件?

    #include <map>
    #include <vector>
    #include <string>
    
    struct privateData {
      map<string,vector<vector<string>>> allData;
      void addDataUnit(const string& block, const vector<string>& unit)
      {
        // I consider that you already parsed csv data into separated elements
        allData[block].push_back(unit);
      }
      string getDataRow(const string& block, int position) {
        string ret;
        if (allData[block].size() >= position) return ret;
        for (unsigned int i = 0; i < allData[block][position].size(); i++) {
          ret+=allData[block][position][i];
          ret+="SomeDelim";
        }
        return ret;
      }
      vector<string> getDataBlock(const string& block) {
        vector<string> ret;
        for (unsigned int i = 0; i < allData[block].size(); i++)
          ret.push_back(getDataRow(block,i));
        return ret;
      }
    
    }
    

    我没有编译 - 所以,可能是一些语法错误。
    因此,每个数据块将被命名为单元集的数组。 然后您可以迭代地图以获取所有名称并将它们写入单独的文件或单独的数据集。
    希望对你有帮助

    【讨论】:

      【解决方案4】:

      检查这个:http://www.cplusplus.com/reference/fstream/ofstream/ofstream/#parameters

      你应该这样写:

      ofstream ofs (path2 + "tanShears.csv", ofstream::out|ofstream::app);
      

      您可以将所有结果存储在向量中,但如果计算过程很长(需要几个小时),则可能会丢失此数据(当某事出错时),在这种情况下,最好将您的结果写入计算每个部分后的文件。

      但是,写入文件完整数据似乎比写入部分数据要快。

      【讨论】:

        最近更新 更多