我的主要问题是,当我从struct Item s打印时,s.name被打印两次。
代码:
#include <stdio.h>
struct Item{
char code[5];
char name[40];
};
int main(){
FILE *f;
struct Item s;
//Open file
f = fopen("ex.txt", "r");
//Read from file
fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);
//Print from file
printf("%s %s", s.code, s.name); //Main problem here
fclose(f);
}
输入(ex.txt):
AB011;Hello World
输出应为:
AB011 Hello World
但是它是:
AB011Hello World Hello World
这里发生了什么?
附加说明:我需要使用fscanf这个,以便我可以了解它是如何工作的。
答案 0 :(得分:3)
在fscanf
的通话中,您正在使用
"%5c;%[a-zA-Z ]\n"
作为格式说明符。格式说明符的%5c
部分将5个字符读取到s.code
。这不会为终止空字符留出空间。
将{作为printf
与%s
说明符的参数用于导致未定义的行为。 %s
需要一个以空字符结尾的字符串。
您应该将code
的大小更改为使用6个字符,然后在fscanf
行之后使用空字符终止它。
#include <stdio.h>
struct Item{
/// CHANGED HERE
char code[6];
char name[40];
};
int main(){
FILE *f;
struct Item s;
//Open file
f = fopen("ex.txt", "r");
//Read from file
fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);
/// CHANGED HERE
s.code[5] = '\0';
//Print from file
printf("%s %s", s.code, s.name);
fclose(f);
}
答案 1 :(得分:2)
如果您在code
中存储5个字符,则大小必须为6个字节,包括\0
终结符。
对于scanf %[5]c
- 只读取5个字符,但不会添加终止\0
。
如果指定的宽度不是1,则该函数会准确读取宽度字符,并将它们存储在作为参数传递的数组的连续位置中。最后不附加空字符。
您需要做的是在最后添加\0
//Read from file
fscanf(f, "%5c;%[a-zA-Z ]\n", s.code, s.name);
s.code[5] = '\0';