C++ 14:基于C文件API的CSV流

开课吧小一2021-05-08 09:47

点赞
有用
分享分享

C ++ 14:基于C File API的CSV流,可从STL文件流中消除代码膨胀

C++ 14:基于C文件API的CSV流

主要动机

该库基于C File API。目的是减少使用C ++ STL流带来的代码膨胀。它的用法类似于 基于C ++文件流的Minimalistic CSV流以及类似的仅标头库。只需将名称空间从更改为mini即可capi。它的某些优化已回溯到Minimalistic CSV Stream版本1.8.3,包括在可能的情况下通过引用传递,将结果与数据成员缓存以及避免返回新字符串对象的操作。读者可以在v1.8.2和v1.8.3之间进行比较以了解差异。

消除误解

单独使用此类不会减少应用程序中的代码膨胀。这将只来约当所有其他fstream,stringstream和cout/cin呼叫拆除或与非STL流等价物所取代。

重大变化

如果重载STL流运算符,而不是自定义数据类型的CSV流运算符,则该类不能只是MiniCSV的直接替代。您必须重载CSV流运算符。

可选依赖项

增强精神气v2

要使用Boost Spirit Qi将字符串转换为数据,请USE_BOOST_SPIRIT_QI在包含标题之前进行定义。

#define USE_BOOST_SPIRIT_QI#include "csv_stream.h"

要将char读取为ASCII而非整数,请CHAR_AS_ASCII在包含头之前定义。

#define CHAR_AS_ASCII#include "csv_stream.h"

警告:此宏检测在v0.5.2中已删除,因为它是全局设置。对于要char作为8位数字整数进行读写的用户,请使用NCharclass。使用os << csv::NChar(ch)写入,但用户可以将它转换为int不使用NChar。并is >> csv::NChar(ch)读取从-127到128的整数作为char变量。

基准

注意:基准测试结果基于最新的minicsv 1.8.2。注意:各种方法只会影响输入流基准测试结果。

文件流基准

// minicsv using std::stringstream
      mini::csv::ofstream:  387ms
      mini::csv::ifstream:  386ms
      // minicsv using Boost lexical_cast
      mini::csv::ofstream:  405ms
      mini::csv::ifstream:  283ms
      // capi csv using to_string
      capi::csv::ofstream:  152ms
      capi::csv::ifstream:  279ms
      // capi csv using Boost Spirit Qi
      capi::csv::ofstream:  163ms
      capi::csv::ifstream:  266ms
      // capi in-memory cached file csv
capi::csv::ocachedfstream:  124ms
capi::csv::icachedfstream:  127ms
      // capi in-memory cached file csv using Boost Spirit Qi
capi::csv::ocachedfstream:  122ms
capi::csv::icachedfstream:  100ms

注意:内存中输入流意味着在处理之前将整个文件加载到内存中。

注意:内存中输出流意味着在保存之前将内容保留在内存中。

警告:内存中的流需要足够的内存才能将文件内容保留在内存中。

字符串流基准

// minicsv using std::stringstream
mini::csv::ostringstream:  362ms
mini::csv::istringstream:  377ms// minicsv using Boost lexical_cast
mini::csv::ostringstream:  383ms
mini::csv::istringstream:  283ms// capi csv
capi::csv::ostringstream:  113ms
capi::csv::istringstream:  127ms// capi csv using Boost Spirit Qi
capi::csv::ostringstream:  116ms
capi::csv::istringstream:  106ms

警告

实例化可能会很慢,因为要初始化的数据成员很多。

文件流的示例代码

#include "csv_stream.h"using namespace capi;

csv::ofstream os("products.txt");
os.set_delimiter(',', "$$");
os.enable_surround_quote_on_str(true, '\"');if (os.is_open())
{
    os << "Shampoo" << 200 << 15.0f << NEWLINE;
    os << "Towel" << 300 << 6.0f << NEWLINE;
}
os.flush();
os.close();

csv::ifstream is("products.txt");
is.set_delimiter(',', "$$");
is.enable_trim_quote_on_str(true, '\"');
if (is.is_open())
{
    std::string name = "";
    int qty = 0;
    float price = 0.0f;
    while (is.read_line())
    {
        try
        {
            is >> name >> qty >> price;
            // display the read items            std::cout << name << "," << qty 
                      << "," << price << std::endl;
        }
        catch (std::runtime_error& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
}

缓存文件流的示例代码

#include "csv_stream.h"using namespace capi;

csv::ocachedfstream os;
os.set_delimiter(',', "$$");
os.enable_surround_quote_on_str(true, '\"');if (os.is_open())
{
    os << "Shampoo" << 200 << 15.0f << NEWLINE;
    os << "Towel" << 300 << 6.0f << NEWLINE;
}
os.write_to_file("products.txt");

csv::icachedfstream is("products.txt");
is.set_delimiter(',', "$$");
is.enable_trim_quote_on_str(true, '\"');
if (is.is_open())
{
    std::string name = "";
    int qty = 0;
    float price = 0.0f;
    while (is.read_line())
    {
        try
        {
            is >> name >> qty >> price;
            // display the read items            std::cout << name << "," << qty 
                      << "," << price << std::endl;
        }
        catch (std::runtime_error& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
}

字符串流的示例代码

#include "csv_stream.h"using namespace capi;

csv::ostringstream os;
os.set_delimiter(',', "$$");
os.enable_surround_quote_on_str(true, '\"');if (os.is_open())
{
    os << "Shampoo" << 200 << 15.0f << NEWLINE;
    os << "Towel" << 300 << 6.0f << NEWLINE;
}
os.write_to_file("products.txt");

csv::istringstream is(os.get_text().c_str());
is.set_delimiter(',', "$$");
is.enable_trim_quote_on_str(true, '\"');
if (is.is_open())
{
    std::string name = "";
    int qty = 0;
    float price = 0.0f;
    while (is.read_line())
    {
        try
        {
            is >> name >> qty >> price;
            // display the read items            std::cout << name << "," << qty 
                      << "," << price << std::endl;
        }
        catch (std::runtime_error& e)
        {
            std::cerr << e.what() << std::endl;
        }
    }
}

输出

档案内容

"Shampoo",200,15.000000"Towel",300,6.000000

显示输出

Shampoo,200,15
Towel,300,6

快速更改定界符

分隔符可以在带有sep类的输入/输出流中即时更改。该示例在文本中以空格和逗号作为分隔符。

// demo sep class usagecsv::istringstream is("vt 37.8,44.32,75.1");
is.set_delimiter(' ', "$$");
csv::sep space(' ', "<space>");
csv::sep comma(',', "<comma>");while (is.read_line())
{
    std::string type;
    float r = 0, b = 0, g = 0;
    is >> space >> type >> comma >> r >> b >> g;
    // display the read items    std::cout << type << "|" << r << "|" << b << "|" << g << std::endl;
}

代码托管在Github上

历史

2017-01-28:版本0.5.0:首次发布

2017年2月19日:版本0.5.1:修复读取字符时的输入流异常

2017年3月12日:版本0.5.2固定一些char输出问题,并加入NChar(char包装)类,以写入到数字值[-127..128]到char变量。

bool test_nchar(bool enable_quote)
{
    csv::ostringstream os;
    os.set_delimiter(',', "$$");
    os.enable_surround_quote_on_str(enable_quote, '\"');

    os << "Wallet" << 56 << NEWLINE;

    csv::istringstream is(os.get_text().c_str());
    is.set_delimiter(',', "$$");
    is.enable_trim_quote_on_str(enable_quote, '\"');

    while (is.read_line())
    {
        try
        {
            std::string dest_name = "";
            char dest_char = 0;

            is >> dest_name >> csv::NChar(dest_char);

            std::cout << dest_name << ", " 
                << (int)dest_char << std::endl;
        }
        catch (std::runtime_error& e)
        {
            std::cerr << __FUNCTION__ << e.what() << std::endl;
        }
    }
    return true;
}

显示输出

Wallet, 56

2017-09-18:版本0.5.3:

如果您的转义参数set_delimiter()为空,带分隔符的文本将自动用引号引起来(以符合Microsoft Excel和常规CSV惯例)

"Hello,World",600

Microsoft Excel和CSV Stream将此读为“ Hello,World”和600。

2018-08-12:版本0.5.4:

添加带有宽字符文件参数的重载文件打开功能(仅在win32上可用)

2021-02-21 :版本0.5.4e:修复了中的无限循环quote_unescape。

2021-05-06: CSV流在存在换行符的情况下检测到行尾。字符串输入中的换行符不可避免地破坏了解析。新版本0.5.5通过转义来换行。

以上就是小编为大家整理的“MLOps具有模型单元测试的连续交付”一文,更多信息尽在AI人工智能教程频道。

相关推荐:

免费领完整的AI学习路径资料,带你轻松入门!

AI资料难找吗?AI免费论文资料,等你领取!

福利来袭!人工智能核心课程优惠名额等你来领

有用
分享