gpt4 book ai didi

c++ - 高效读取 3MB 文本文件,包括。解析

转载 作者:行者123 更新时间:2023-11-30 03:30:15 25 4
gpt4 key购买 nike

我有几个 ~3MB 的文本文件需要用 C++ 解析。

文本文件如下所示 (1024x786):

12,23   45,78   90,12   34,56   78,90   ...
12,23 45,78 90,12 34,56 78,90 ...
12,23 45,78 90,12 34,56 78,90 ...
12,23 45,78 90,12 34,56 78,90 ...
12,23 45,78 90,12 34,56 78,90 ...

表示由 Tab 分隔的“数字 block ”,数字本身包含 ,(由 . 代替)小数点标记。

首先我需要读取文件。目前我正在使用这个:

#include <boost/tokenizer.hpp>

string line;
ifstream myfile(file);
if (myfile.is_open())
{
char_separator<char> sep("\t");
tokenizer<char_separator<char>> tokens(line, sep);
}
myfile.close();

在获取“数字 block ”方面效果很好,但我仍然需要将此 char 转换为 float ,但将 , 处理为小数点.由于文件大小,我认为将其 tokenize 也不是一个好主意。此外,我需要将所有这些值添加到一个数据结构中,之后我可以按位置访问该数据结构(例如 [x][y])。有什么想法可以实现吗?

最佳答案

您可以使用 Boost.Spirit解析文件的内容,作为最终结果,您可能会从解析器中获得您喜欢的结构化数据,例如 std::vector<std::vector<float>> . IMO,您的普通文件的大小并不大。我相信最好将整个文件读入内存并执行解析器。下面的 read_file 显示了读取文件的有效解决方案。 .

qi::float_解析一个长度和大小受 float 限制的实数类型,它使用 . (点)作为分隔符。您可以通过 qi::real_policies<T>::parse_dot 自定义分隔符.下面我使用了来自 spirit/example/qi/german_floating_point.cpp 的代码片段.

看看这个演示:

#include <boost/spirit/include/qi.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

std::string read_file(std::string path)
{
std::string str;
std::ifstream file( path, std::ios::ate);
if (!file) return str;
auto size(file.tellg());
str.resize(size);
file.seekg(0, std::ios::beg);
file.rdbuf()->sgetn(&str[0], size);
return str;
}

using namespace boost::spirit;

//From Boost.Spirit example `qi/german_floating_point.cpp`
//Begin
template <typename T>
struct german_real_policies : qi::real_policies<T>
{
template <typename Iterator>
static bool parse_dot(Iterator& first, Iterator const& last)
{
if (first == last || *first != ',')
return false;
++first;
return true;
}
};

qi::real_parser<float, german_real_policies<float> > const german_float;
//End

int main()
{
std::string in(read_file("input"));
std::vector<std::vector<float>> out;
auto ret = qi::phrase_parse(in.begin(), in.end(),
+(+(german_float - qi::eol) >> qi::eol),
boost::spirit::ascii::blank_type{},
out);
if(ret && in.begin() == in.end())
std::cout << "Success" << std::endl;
}

关于c++ - 高效读取 3MB 文本文件,包括。解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45133705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com