我有一个文件,其中的行以'\ n'分隔,其中每行看起来都是
10010 0 19 7 18
或
10014 -1 -1 -1 11 10db8 1
也就是说,每一行总是要有5或7个空格分隔值,并且每个值的类型也是事先已知的。我想逐行读取文件并解析每一行以提取inttypes(SCNi32,SCNu32,SCNx32 ..)并存储在相应的inttype变量中。最简单的方法是什么?我是C的新手。
答案 0 :(得分:0)
使用fgets()
读取该行,将该行拆分为令牌。
使用strtok()
将行划分为令牌。
使用atoi()
或任何其他字符串将整数转换为整数。
答案 1 :(得分:0)
您应该创建一个结构来存储它们,例如:
typedef struct
{
int16_t a;
uint32_t b;
int8_t c;
...
} int_stuff_t;
然后你可以写一个长列表,如
#define GET_FORMAT_SPECIFIER(type) _Generic((type), \
int16_t: "%"SCNd16, \
uint32_t: "%"SCNu32, \
int8_t: "%"SCNd8)
fscanf(fp, GET_FORMAT_SPECIFIER(int_stuff.a), &int_stuff.a);
fscanf(fp, GET_FORMAT_SPECIFIER(int_stuff.b), &int_stuff.b);
...
现在,如果你有很多这些并且它们有各种各样的名称和格式,那么这可能是你应该考虑使用X宏的少数有效案例之一,以使代码易于维护。
示例:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <assert.h>
// X macro (type, name, format)
#define INT_STUFF_LIST \
X(int16_t, a, SCNd16) \
X(uint32_t, b, SCNu32) \
X(int8_t, c, SCNd8)
typedef struct
{
#define X(type, name, format) \
type name;
INT_STUFF_LIST
#undef X
} int_stuff_t;
int main()
{
FILE* fp = fopen("something.txt", "r");
assert(fp != NULL);
int_stuff_t int_stuff;
#define X(type, name, format) \
fscanf(fp, "%" format, &int_stuff.name);
INT_STUFF_LIST
#undef X
fclose(fp);
}
虽然这只是一个快速的&amp;肮脏的例子,真实的代码应该不断检查每个fscanf调用的结果,以确保它不是EOF。