读取保存在文件中的uint32_t变量时出错

时间:2017-04-14 23:44:36

标签: c uint32

我有一个问题,即将uint32_t值写入文件并将其读回。 要将其写入文件,我使用

uint32_t num = 2036465665 ; 
FILE *fp = fopen("test.dat", "w");
fprintf(fp,"value = %" PRIu32 "\n", num);
fclose(fp);

为了阅读它,我首先将文件的内容复制到数组data[]中,然后逐行提取值。

int len = 100;
char *line = malloc(len * sizeof(char));
char field[256], tmp[2];

FILE *fp = fopen("test.dat", "r");
while ( -1 != getline(&line, &len, fp)){
            char *value=malloc(sizeof(char)*256);
            sscanf( line, "%s %s %s", field, tmp, value);
            data[i] = value;
            i++;
        }
 fclose(fp);

要读取uint32_t变量的值,我会使用不同的atoistrtoul得到不同的值,而不是写入文件的确切值。

uint32_t read_num;
read_num = strtoul (data[0], NULL, 32);

这使read_num的值为1345324165。

read_num = (uint32_t) atoi(data[0]);

给出3226523632

如何获取文件中保存的正确值。是(i)使用sscanf将文件内容读入字符串或(ii)strtoulatoi(iii)基于strtoul()的错误。

1 个答案:

答案 0 :(得分:0)

我将你的代码片段调整到这个接近MCVE(Minimum, Complete, Verifiable Example),它似乎在运行macOS Sierra 10.12.4的Mac上使用GCC 6.3.0作为编译器正常工作。 (我也使用clang - Apple LLVM版本8.1.0(clang-802.0.41)获得相同的结果。)

#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>

static void write_data(const char *filename)
{
    uint32_t num = 2036465665; 
    FILE *fp = fopen(filename, "w");
    assert(fp != NULL);
    fprintf(fp,"value = %" PRIu32 "\n", num);
    printf("Wrote %" PRIu32 "\n", num);
    fclose(fp);
}

int main(void)
{
    const char filename[] = "test.dat";

    write_data(filename);

    char *data[10];
    size_t len = 100;
    char *line = malloc(len * sizeof(char));
    assert(line != 0);
    char field[256], tmp[2];

    FILE *fp = fopen(filename, "r");
    assert(fp != NULL);
    int i = 0;
    while ( -1 != getline(&line, &len, fp))
    {
        printf("Read: [%s]\n", line);
        char *value = malloc(sizeof(char)*256);
        assert(value != 0);
        if (sscanf(line, "%s %1s %s", field, tmp, value) != 3)
            assert(0);
        printf("Field [%s] tmp [%s] value [%s]\n", field, tmp, value);
        data[i] = value;
        i++;
    }
    free(line);
    fclose(fp);

    char *endptr;
    errno = 0;
    printf("Processing [%s]\n", data[0]);
    uint32_t read_num = strtoul(data[0], &endptr, 10);
    assert(endptr != data[0]);
    free(data[0]);

    printf("Number read: %" PRIu32 "\n", read_num);
    return 0;
}

使用assert进行错误处理是极端的懒惰,但优于不检查。 strtoul()之后的错误检查也很草率 - 有未经检查的条件(read_num == ULONG_MAXerrno == ERANGE等)。

编译运行时,我得到:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
>     -Wstrict-prototypes -Wold-style-definition rd53.c -o rd53
$ ./rd53
Wrote 2036465665
Read: [value = 2036465665
]
Field [value] tmp [=] value [2036465665]
Processing [2036465665]
Number read: 2036465665
$

如果使用size_t len vs int len不是您的问题,也许您可​​以尝试使用此代码并查看它给您的内容。