gpt4 book ai didi

c++ - 从内存映射格式化文件中读取整数

转载 作者:可可西里 更新时间:2023-11-01 10:40:09 25 4
gpt4 key购买 nike

我在内存中映射了一个大型格式化(文本)文件,每行包含一个整数,如下所示:

123
345
34324
3232
...

所以,我在第一个字节有一个指向内存的指针,在最后一个字节有一个指向内存的指针。我正在尝试尽快将所有这些整数读入数组。最初我创建了一个专门的 std::streambuf 类来与 std::istream 一起从该内存中读取数据,但它似乎相对较慢。

对于如何有效地将“1231232\r\n123123\r\n123\r\n1231\r\n2387897...”之类的字符串解析为数组 {1231232,123123,1231,231, 2387897,...} ?

事先不知道文件中整数的数量。

最佳答案

这对我来说是一项非常有趣的任务,可以让我更多地了解 C++。

诚然,代码非常大并且有很多错误检查,但这只能说明在解析过程中有多少不同的地方可能出错。

#include <ctype.h>
#include <limits.h>
#include <stdio.h>

#include <iterator>
#include <vector>
#include <string>

static void
die(const char *reason)
{
fprintf(stderr, "aborted (%s)\n", reason);
exit(EXIT_FAILURE);
}

template <class BytePtr>
static bool
read_uint(BytePtr *begin_ref, BytePtr end, unsigned int *out)
{
const unsigned int MAX_DIV = UINT_MAX / 10;
const unsigned int MAX_MOD = UINT_MAX % 10;

BytePtr begin = *begin_ref;
unsigned int n = 0;

while (begin != end && '0' <= *begin && *begin <= '9') {
unsigned digit = *begin - '0';
if (n > MAX_DIV || (n == MAX_DIV && digit > MAX_MOD))
die("unsigned overflow");
n = 10 * n + digit;
begin++;
}

if (begin == *begin_ref)
return false;

*begin_ref = begin;
*out = n;
return true;
}

template <class BytePtr, class IntConsumer>
void
parse_ints(BytePtr begin, BytePtr end, IntConsumer out)
{
while (true) {
while (begin != end && *begin == (unsigned char) *begin && isspace(*begin))
begin++;
if (begin == end)
return;

bool negative = *begin == '-';
if (negative) {
begin++;
if (begin == end)
die("minus at end of input");
}

unsigned int un;
if (!read_uint(&begin, end, &un))
die("no number found");

if (!negative && un > INT_MAX)
die("too large positive");
if (negative && un > -((unsigned int)INT_MIN))
die("too small negative");

int n = negative ? -un : un;
*out++ = n;
}
}

static void
print(int x)
{
printf("%d\n", x);
}

int
main()
{
std::vector<int> result;
std::string input("2147483647 -2147483648 0 00000 1 2 32767 4 -17 6");

parse_ints(input.begin(), input.end(), back_inserter(result));

std::for_each(result.begin(), result.end(), print);
return 0;
}

我尽量不调用任何类型的未定义行为,这在将无符号数转换为有符号数或在未知数据类型上调用 isspace 时会变得非常棘手。

关于c++ - 从内存映射格式化文件中读取整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4198404/

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