gpt4 book ai didi

C++ - 如何使用流来解析文件?

转载 作者:可可西里 更新时间:2023-11-01 18:25:55 27 4
gpt4 key购买 nike

我有一个文件,我需要遍历它并分配一个 int foo,字符串类型,64/128 位长。我将如何使用流将这些行解析为以下变量 - 我想坚持使用流语法( ifs >> foo >> type )但在这种情况下 type 最终将成为 0/之后的其余行52 ...那时我只得到一个 char* 并使用 strtoull 等等,所以为什么首先使用流...我希望可读代码没有 char strings/strtok/strtoull 的可怕性能

//input file:
0ULL'04001C0180000000000000000EE317BC'
52L'04001C0180000000'
//ouput:
//0 ULL 0x04001C0180000000 0x000000000EE317BC
//52 L 0x04001C0180000000

ifstream ifs("input.data");
int foo;
string type;
unsigned long long ull[2];

最佳答案

Boost Spirit 实现

这是强制性的基于 Boost Spirit (Qi) 的实现。为了更好地衡量,包括使用 Boost Spirit (Karma) 进行格式化:

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

namespace karma=boost::spirit::karma;
namespace qi =boost::spirit::qi;

static qi::uint_parser<unsigned long long, 16, 16, 16> hex16_p; // parse long hex
static karma::uint_generator<unsigned long long, 16> hex16_f; // format long hex

int main(int argc, char** args)
{
std::ifstream ifs("input.data");
std::string line;
while (std::getline(ifs, line))
{
std::string::iterator begin = line.begin(), end = line.end();

int f0;
std::string f1;
std::vector<unsigned long long> f2;

bool ok = parse(begin, end,
qi::int_ // an integer
>> *qi::alpha // alternatively: *(qi::char_ - '\'')
>> '\'' >> +hex16_p >> '\'' // accepts 'n x 16' hex digits
, f0, f1, f2);

if (ok)
std::cout << "Parsed: " << karma::format(
karma::int_
<< ' ' << karma::string
<< ' ' << ("0x" << hex16_f) % ' '
, f0, f1, f2) << std::endl;
else
std::cerr << "Parse failed: " << line << std::endl;
}

return 0;
}

测试运行:

Parsed: 0 ULL 0x4001c0180000000 0xee317bc
Parsed: 52 L 0x4001c0180000000

请参阅下面的调整和示例,了解有关如何调整的信息,例如十六进制输出

基准

我已经对 @Cubbi's version 进行了基准测试以及上面的所写,是您提供的示例输入的 100,000 倍。这最初使 Cubbi 的版本略有优势:0.786s 对比 0.823s

现在,这当然是不公平的比较,因为我的代码每次都在动态构建解析器。像这样从循环中取出:

typedef std::string::iterator It;

const static qi::rule<It> parser = qi::int_ >> *qi::alpha >> '\'' >> +hex16_p >> '\'';
bool ok = parse(begin, end, parser, f0, f1, f2);

Boost Spirit 仅以 0.093s 脱颖而出;已经快了 8.5 倍,即使每次迭代仍在构建业力格式化程序也是如此。

在两个版本中都注释掉了输出格式后,Boost Spirit 快了 11 倍

调整、示例

请注意如何轻松调整内容:

//  >> '\'' >> +hex16_p >> '\'' // accepts 'n x 16' hex digits
>> '\'' >> qi::repeat(1,2)[ hex16_p ] >> '\'' // accept 16 or 32 digits

或者像输入一样格式化十六进制输出:

// ("0x" << hex16_f) % ' '
karma::right_align(16, '0')[ karma::upper [ hex16_f ] ] % ""

更改示例输出:

0ULL'04001C0180000000000000000EE317BC'
Parsed: 0 ULL 04001C0180000000000000000EE317BC
52L'04001C0180000000'
Parsed: 52 L 04001C0180000000

HTH

关于C++ - 如何使用流来解析文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6206302/

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