如何解决将文件读入包含C枚举的typedef结构中?
我在将文件读入包含typedef struct
的{{1}}时遇到麻烦。我是C语言的初学者,所以我真的不知道该如何使用枚举读取文件。
我能够用简单的代码读取文件并打印出内容,但是我需要读取文件并将行中的每个字符串分配给typedef结构中的类型。
输入文件如下所示:
enum
这些是我代码的相关部分:
random.num year model category
Example:
54 2012 model1 type1
我得到了错误:
格式为'%s'的参数应为'char *'类型,而参数6的类型为'category * {aka枚举*}'
由于我是C语言的新手,所以我对如何将文件读入结构感到困惑。我要为typedef enum { type1,type2,type3,type4} category;
typedef struct {
int num;
int year;
char make[MAX_MAKE_CHARS];
category category; //enum from above
}item;
//reading in the file I have this:
int create_db(char *f){
char file_contents[100]; // read the file --> ("r") FILE *f = fopen(f,"r");
// check if file can be used
if(f == NULL){
printf("File not found");
exit(1);
}
int i = 0; item item_array[100];
while(fscanf(f,"%d %d %s %s",&item[i].num,&item[i].year,item[i].make,item[i].category) != EOF){
// can't get past the while look where it says "item[i].category
做些什么?
解决方法
不幸的是,枚举是仅在代码中有效的符号,并且无法在运行时以字符串形式访问此符号。实际上,任何enum
变量都存储为整数
但是您可以做些什么:
- 定义一个
char *
数组,其中包含枚举的符号作为字符串 - 将输入文件中包含的
enum
符号存储在临时字符串中 - 检查
scanf
的返回值 - 调用一个实用函数,在常量字符串数组中搜索临时字符串并返回相应的枚举值
- 如果找不到该字符串,则会引发错误
- 如果找到了字符串,请将枚举值存储在输出结构中
在以下示例代码中,为清楚起见,我省略了您的while
(您将可以根据问题中未描述的要求将其重新添加):
int tmp_num;
int tmp_year;
char tmp_make[100];
char tmp_category_str[10]; // <-- define the size according to the max enum symbol length
if(fscanf(f,"%d %d %99s %9s",&tmp_num,&tmp_year,tmp_make,tmp_category_str) == 4)
{
int tmp_category;
if( ( tmp_category = check_enum( tmp_category_str ) ) != -1 )
{
Item.num = tmp_num;
Item.year = tmp_year;
strcpy( make,tmp_make );
Item.category = ( category )tmp_category; // The numeric value is stored in the struct
}
else
{
printf( "Invalid 'category' value!\n" );
}
}
请注意:
- 我希望
fscanf
的返回值为4 - 我将
make
的大小更改为100。为了简单起见,为了安全起见,格式说明符%s
应当包含arr_size-1
个字符的限制 - 如果提供了不匹配任何枚举符号的奇怪字符串值,
check_enum()
将返回-1
现在,仅缺少check_enum()
实现。只需在enumSymbols[]
个元素上循环搜索输入字符串即可。
char* enumSymbols[] = { "type1","type2","type3","type4" };
int check_enum(char * str)
{
int ret = -1;
if( str )
{
for( int i=0; i<(sizeof(enumSymbols)/sizeof(enumSymbols[0])); i++ )
{
if( strcmp(enumSymbols[i],str) == 0 )
{
ret = i;
break;
}
}
}
return ret;
}
注意:,它可以工作,但是您必须保持数组和枚举对齐。为了防止人为调整错误,可以实施类似this one的解决方案。在此答案中,我解释了如何创建对齐的 enum / struct 对,但是以相同的方式并使用preprocessor stringifier operator #
也是对齐的 enum / string数组对可以生成。
Roberto's answer很不错,其中包含最关键的信息:
任何枚举变量实际上都存储为整数
如果您能够将输入格式从枚举的字符串表示形式更改为整数(即在输入中使用<!DOCTYPE html>
<html>
<head>
<title>Simple Map</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap&libraries=&v=weekly" defer></script>
<!-- jsFiddle will insert css and js -->
</head>
<body>
<div id="map"></div>
</body>
</html>
而不是0
,则可以使用{{1 }}。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。