【问题标题】:Writing .csv files from C++从 C++ 编写 .csv 文件
【发布时间】:2014-08-08 10:14:43
【问题描述】:

我正在尝试将一些数据输出到 .csv 文件,它正在将其输出到文件中,但它没有将数据分成不同的列,并且似乎输出数据不正确。

    ofstream Morison_File ("linear_wave_loading.csv");         //Opening file to print info to
    Morison_File << "Time Force(N/m)" << endl;          //Headings for file
    for (t = 0; t <= 20; t++) {
      u = sin(omega * t);
      du = cos(omega * t); 
      F = (0.5 * rho * C_d * D * u * fabs(u)) + rho * Area * C_m * du; 

      cout << "t = " << t << "\t\tF = " << F << endl;
      Morison_File << t;                                 //Printing to file
      Morison_File << F;

    }

     Morison_File.close();

时间和力(N/m)分别在 A 和 B 列中,但 t 和 F 值都在打印第一行。

将它们分开以将 t 打印到 A 列和 F 打印到 B 列的语法是什么?

【问题讨论】:

  • 您可以使用分隔符,例如 ;,这通常由电子表格编辑器支持,而不是制表
  • “CSV”中的“S”代表“分离”。你不写任何分隔符。不在值之间,也不在记录末尾。
  • 顺便说一下,标题本身并没有用制表符分隔时间和力量
  • 我之前确实在它们之间使用了逗号,但这也不起作用。为了分隔 t 和 F,它们之间只有一个空格,两个空格将它们隔开两列。
  • @remi ;他们之间也没有工作......

标签: c++ csv


【解决方案1】:

CSV 文件没有什么特别之处。您可以使用文本编辑器创建它们,只需遵循basic rules。 RFC 4180 (tools.ietf.org/html/rfc4180) 接受的分隔符是逗号 ',而不是分号 ';'。 MS Excel 等程序需要逗号作为分隔符。

有些程序将逗号视为小数,将分号视为分隔符,但这些程序在技术上超出了 CSV 格式文件的“公认”标准。

因此,在创建 CSV 时,您会创建文件流并像这样添加行:

#include <iostream>
#include <fstream>
int main( int argc, char* argv[] )
{
      std::ofstream myfile;
      myfile.open ("example.csv");
      myfile << "This is the first cell in the first column.\n";
      myfile << "a,b,c,\n";
      myfile << "c,s,v,\n";
      myfile << "1,2,3.456\n";
      myfile << "semi;colon";
      myfile.close();
      return 0;
}

这将导致在 MS Excel 中打开时的 CSV 文件如下所示:

【讨论】:

  • MS Excel 将根据用户的区域设置以不同方式解释 CSV 文件。 “欧洲” Excel 需要用分号分隔的字段(并使用逗号作为小数点)。
  • 我的 Excel 需要分号,但我的 Libre Office 只给了我一堆东方字符。你知道为什么吗?
  • 我不熟悉 Libre Office,但根据他们的网站,您可能需要在导入 csv 时设置列分隔符。说明在这里:help.libreoffice.org/Calc/Importing_and_Exporting_CSV_Files
  • 您忘记转义包含分隔符的值。
  • 我在使用上面的代码调用 close() 时遇到访问冲突错误。但这对我有用:std::fstream myFile; myfile.open ("example.csv", std::ios::out | std::ios::app);
【解决方案2】:

这是一个类似 STL 的类

文件“csvfile.h”

#pragma once

#include <iostream>
#include <fstream>

class csvfile;

inline static csvfile& endrow(csvfile& file);
inline static csvfile& flush(csvfile& file);

class csvfile
{
    std::ofstream fs_;
    const std::string separator_;
public:
    csvfile(const std::string filename, const std::string separator = ";")
        : fs_()
        , separator_(separator)
    {
        fs_.exceptions(std::ios::failbit | std::ios::badbit);
        fs_.open(filename);
    }

    ~csvfile()
    {
        flush();
        fs_.close();
    }

    void flush()
    {
        fs_.flush();
    }

    void endrow()
    {
        fs_ << std::endl;
    }

    csvfile& operator << ( csvfile& (* val)(csvfile&))
    {
        return val(*this);
    }

    csvfile& operator << (const char * val)
    {
        fs_ << '"' << val << '"' << separator_;
        return *this;
    }

    csvfile& operator << (const std::string & val)
    {
        fs_ << '"' << val << '"' << separator_;
        return *this;
    }

    template<typename T>
    csvfile& operator << (const T& val)
    {
        fs_ << val << separator_;
        return *this;
    }
};


inline static csvfile& endrow(csvfile& file)
{
    file.endrow();
    return file;
}

inline static csvfile& flush(csvfile& file)
{
    file.flush();
    return file;
}

文件“main.cpp”

#include "csvfile.h"

int main()
{
    try
    {
        csvfile csv("MyTable.csv"); // throws exceptions!
        // Header
        csv << "X" << "VALUE"        << endrow;
        // Data
        csv <<  1  << "String value" << endrow;
        csv <<  2  << 123            << endrow;
        csv <<  3  << 1.f            << endrow;
        csv <<  4  << 1.2            << endrow;
    }
    catch (const std::exception& ex)
    {
        std::cout << "Exception was thrown: " << e.what() << std::endl;
    }
    return 0;
}

最新版here

【讨论】:

  • 如果需要一个开放的std::ostream 来处理这个 csv-writer 类,它的帮助会更大,想想std::stringbuf
【解决方案3】:

改变

Morison_File << t;                                 //Printing to file
Morison_File << F;

Morison_File << t << ";" << F << endl;                                 //Printing to file

a , 也可以代替 ;

【讨论】:

    【解决方案4】:

    你必须“;”分隔符,CSV => 逗号分隔值

     ofstream Morison_File ("linear_wave_loading.csv");         //Opening file to print info to
        Morison_File << "'Time'; 'Force(N/m)' " << endl;          //Headings for file
        for (t = 0; t <= 20; t++) {
          u = sin(omega * t);
          du = cos(omega * t); 
          F = (0.5 * rho * C_d * D * u * fabs(u)) + rho * Area * C_m * du; 
    
          cout << "t = " << t << "\t\tF = " << F << endl;
          Morison_File << t << ";" << F;
    
        }
    
         Morison_File.close();
    

    【讨论】:

      【解决方案5】:

      如果您使用 C++ 写入 .csv 文件 - 您应该使用以下语法:

      myfile <<" %s; %s; %d", string1, string2, double1 <<endl;
      

      这会将三个变量(字符串 1&2 和 double1)写入单独的列,并在它们下方留下一个空行。在excel中;表示新行,所以如果你只想换一个新行 - 你也可以写一个简单的“;”在将新数据写入文件之前。如果您不想在下面有一个空行 - 您应该删除 endl 并使用:

      myfile.open("result.csv", std::ios::out | std::ios::app);
      

      打开 .csv 文件时的语法(例如 result.csv)。通过这种方式,下次您将某些内容写入 result.csv 文件时 - 它会将其写入最后一行的正下方的新行中 - 因此您可以轻松管理 for 循环。

      【讨论】:

      • 我怀疑myfile &lt;&lt;" %s; %s; %d", string1, string2, double1 &lt;&lt;endl; 会起作用。应该是什么版本的 C++?
      【解决方案6】:

      正如@kris 上面所解释的,根据 MS Excel 的区域配置,它不会将逗号解释为分隔符。就我而言,我不得不将其更改为分号

      【讨论】:

      • 一个例子可能有用。 @user3460758 评论说分号对他不起作用。除非一个或多个值有逗号,否则逗号应该没有任何问题,然后通常最好用逗号将引号括起来,例如。 5,"2,000",12
      • 正如我所说,这是一个 Excel 区域配置问题,如前所述。看不出我如何从这个陈述中产生和举例。
      猜你喜欢
      • 2016-11-28
      • 2011-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-24
      相关资源
      最近更新 更多