解析C中一行中不同类型整数的变量数
我有一个文件,其中的行由“\n”分隔,其中每一行看起来像解析C中一行中不同类型整数的变量数,c,parsing,arguments,scanf,fgets,C,Parsing,Arguments,Scanf,Fgets,我有一个文件,其中的行由“\n”分隔,其中每一行看起来像 10010 0 19 7 18 或 也就是说,每一行总是有5个或7个空格分隔的值,并且每个值的类型也是事先知道的。我想逐行读取文件,并解析每一行以提取inttypes(SCNi32、SCNu32、SCNx32..)并存储在相应的inttype变量中。最简单的方法是什么?我是C的新手 使用fgets()读取该行。通过将该行拆分为标记来解析该行 使用strtok()将行拆分为令牌 使用atoi()或任何其他字符串将令牌转换为整数 您可能应该
10010 0 19 7 18
或
也就是说,每一行总是有5个或7个空格分隔的值,并且每个值的类型也是事先知道的。我想逐行读取文件,并解析每一行以提取inttypes(SCNi32、SCNu32、SCNx32..)并存储在相应的inttype变量中。最简单的方法是什么?我是C的新手
fgets()读取该行。
通过将该行拆分为标记来解析该行strtok()
将行拆分为令牌atoi()
或任何其他字符串将令牌转换为整数您可能应该创建一个结构来存储它们,例如:
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);
}
#包括
#包括
#包括
#包括
//X宏(类型、名称、格式)
#定义INT_STUFF_列表\
X(int16_t,a,SCNd16)\
X(uint32_t,b,SCNu32)\
X(int8_t,c,SCNd8)
类型定义结构
{
#定义X(类型、名称、格式)\
类型名称;
国际材料清单
#未定义X
}内部材料;
int main()
{
FILE*fp=fopen(“something.txt”、“r”);
断言(fp!=NULL);
int_stuff_t int_stuff;
#定义X(类型、名称、格式)\
fscanf(fp,“%”格式和int_stuff.name);
国际材料清单
#未定义X
fclose(fp);
}
虽然这只是一个快速而肮脏的示例,但真正的代码应该不断检查每个fscanf调用的结果,以确保它不是EOF。正确的方法是阅读C库参考,找出需要使用的函数,然后使用它们。你似乎已经准备好了一个计划,执行它吧。
#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);
}