我想我已经尝试了任何东西(刷新stdin,scanf来消费换行等),但没有任何效果,正如我所希望的那样。出于某种原因,第3次扫描会在以下代码中修改第2次扫描的变量:
#include <stdio.h>
int main()
{
char first_name[16], last_name[21];
char filename[11];
FILE *opening;
printf("The program saves your first and last name into a file.\n");
printf("Enter your first name:");
scanf("%s", first_name);
getchar();
printf("Enter your last name:");
scanf(" %s", last_name);
getchar();
printf("File where you want to save your name:");
scanf(" %s", filename);
opening = fopen(filename, "wb");
fprintf(opening, "%s %s", first_name, last_name);
printf("\nSuccessfully saved the data!");
fclose(opening);
return 0;
}
输出:
The program saves your first and last name into a file.
Enter your first name: John
Enter your last name: Doe
File where you want to save your name: filename.txt
Successfully saved the data!
除了filename.txt的内容是这样的所有细节和花花公子:
John t
我猜测't'字符来自某个'txt',但我刚开始学习C而且我不知道如何解决这段代码。请问大师能帮帮我吗?
答案 0 :(得分:1)
您的filename
缓冲区太小。
你写了filename.txt
,这是12个字符,加上零来完成它,得到13.你只分配11.试试这样:
char filename[20];
它应该有效。
使用scanf
时要小心,它会导致非常讨厌的问题,就像你现在遇到的那样。它非常适合实验和学习C,因为它向您展示了正确的内存处理是多么重要。对于任何实际项目,您应该考虑使用不同的功能或框架。
答案 1 :(得分:0)
如果您输入filename.txt作为文件名,那么您将超出filename
的缓冲区。那是未定义的行为,是造成奇怪结果的原因。
要修复,请使char filename[11];
更大,记住为NULL终止符允许1个额外字符。在您的特定情况下,char filename[14];
允许在%s
来电中scanf
之前存在错误空格。
否则,一切看起来都很好。
答案 2 :(得分:0)
在字符串上使用scanf()
是危险的,因为它可以在缓冲区提供内存的更多数据中读取。
如果在字符串中扫描,则应通过将此数字添加到传递给scanf()
的格式,告诉scanf()
要读取多少字符:
char file_name[11];
...
scanf("%10s", file_name); /* As file_name provides memor for 11 characters, read a
maximum of 10 characters into file_name leaving 1
character room for the necessary `0-`terminator indicating
the end of the "string". */
此外,您的代码错过了fopen
系统调用的错误检查。
最好做这样的事情:
opening = fopen(filename, "wb");
if (NULL == opening)
{
perror("fopen() failed");
exit(EXIT_FAILURE);
}