我有一个问题,即将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变量的值,我会使用不同的atoi
和strtoul
得到不同的值,而不是写入文件的确切值。
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)strtoul
与atoi
(iii)基于strtoul()
的错误。
答案 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_MAX
和errno == 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
不是您的问题,也许您可以尝试使用此代码并查看它给您的内容。