我试图将一个句子字符串写入文本文件,但是当我这样做时,它会复制或者重复。为什么会这样,如何让它只打印一次?
节目摘录:
FILE *memberAdd;
typedef struct {
char id[5], name[100];
} Member;
Member reg;
strcpy(reg.id, "M0001");
printf("Name: ");
rewind(stdin);
scanf("%[^\n]", reg.name);
memberAdd = fopen("member.txt", "a");
fprintf(memberAdd, "%s %s\n", reg.id, reg.name);
fclose(memberAdd);
运行上述内容时,文本文件中的输出(reg.name
输入为Test Name
):
M0001测试名称测试名称
答案 0 :(得分:2)
此:
SELECT *
FROM T1
WHERE ID NOT IN(SELECT ID FROM t2)
是缓冲区溢出,char id[5];
strcpy(reg.id, "M0001");
将在末尾写入0终止字符,溢出strpcy()
数组。你得到了未定义的行为。要修复它,可以缩短ID字符串,或者增加数组的大小。
答案 1 :(得分:2)
在您的代码中
ìd
是 off-by-one 。您无法使用 strcpy(reg.id, "M0001");
将"M0001"
(5 chars
和null-terminator)中的字符串存储在5 char
的数组中。您在分配的内存之外访问,这会导致undefined behavior。
引用strcpy()
,章节§7.24.2.3
C11
函数复制strcpy
指向的字符串(包括终止空值) 字符)到s2
指向的数组中。 [...]
因此,暗示目标必须能够保存源字符串,包括空终止符。事实证明,你在这里缺乏记忆力。 :)
如果您计划将s1
数组用作字符串,则还需要使用内存来存储空终止符。在这种情况下,您可以增加成员char
维度以保留终止空值,例如
id
答案 2 :(得分:1)
每个C字符串都需要被某个 NUL 字节终止(即(char)0
)。
所以"M0001"
需要六个(不是5!)字节。你的 字段不够广泛。您获得了buffer overflow,undefined behavior的实例。你应该声明char id[5]
char id[6];
至少作为Member
中的字段。我实际上建议把它做大,也许是char id[8];