C语言中的Scanf文本溢出

C语言中的Scanf文本溢出,c,overflow,scanf,C,Overflow,Scanf,我刚刚开始学习C语言。下面是我正在试验的一些示例代码。它只是为了得到一个用户名。如果我为第一个答案输入一个字符串,该字符串需要一个字符,那么第一个字母将保存为middleInitial,但是被忽略的字符串的其余部分将被后续的scanf读取并保存。这意味着输入“Jacob”然后输入“Pat Smith”将导致输出“Your name is acob J Pat”为什么会发生这种情况 char middleInitial; printf("What is your middle initial?"

我刚刚开始学习C语言。下面是我正在试验的一些示例代码。它只是为了得到一个用户名。如果我为第一个答案输入一个字符串,该字符串需要一个字符,那么第一个字母将保存为middleInitial,但是被忽略的字符串的其余部分将被后续的scanf读取并保存。这意味着输入“Jacob”然后输入“Pat Smith”将导致输出“Your name is acob J Pat”为什么会发生这种情况

char middleInitial; 
printf("What is your middle initial?");

scanf(" %c", &middleInitial);

char firstName[30], lastName[30];

printf("What is your name? ");

scanf(" %s %s", firstName, lastName);

printf("Your name is %s %c %s", firstName, middleInitial, lastName);

原因是第一个
scanf
未提取的剩余字符保留在
STDIN
缓冲区中,然后由后续的
scanf
处理<在阅读
firstname
lastname
之前,请先刷新
STDIN。
由于
fflush
不是删除STDIN缓冲区中不需要的字符的可靠方法,因此解释了手动方式

根据代码:

scanf(" %c", &middleInitial);
获取输入的唯一第一个字符

例如:yout输入“Jacob”,然后输入“John Smith”:

你应该试试:

char middleInitial;
char str[30];
printf("What is your middle name?");

scanf(" %c", &middleInitial); // get "J"
scanf(" %s", &str);  // get "acob"
char firstName[30], lastName[30];

printf("What is your name? ");

scanf(" %s %s", firstName, lastName);

printf("Your name is %s %c %s", firstName, middleInitial, lastName);

我对C中字符串(char*)的用法有一些建议。 首先,正如sumithdev所说,在输入任何信息之前,使用fflush(stdin)清理输入流缓冲区。 第二,尝试使用统一样式存储所有字符串数据。例如,您的middleInitial也可以定义为字符数组,但长度可以为2(middleInitial[0]将是一个字符,middleInitial[1]将是一个“\0”)。 最后一条建议是——尝试使用健壮的函数来防止内存冲突和数据丢失。 代码:

scanf(" %s %s", firstName, lastName);
我看到了潜在的问题:

a) 一般来说,用户的名字或姓氏可以是多个单词,但一个%s在scanf中读取字符直到空格

b) 名字或姓氏可以大于29个字母,数组中的30个元素不足以存储输入,这将导致运行时问题

c) 当您想要更改输入名称不同部分的顺序或添加一些检查时,您的代码中会有很多硬修改

考虑以下版本:

char middleInitial[2]; 
char firstName[30], lastName[30];
// asking for middle part
printf("What is your middle initial? ");
fflush(stdin); // delet all previous inputs
scanf("%1s", middleInitial); // wait new inputs and take only 1 character
// asking for first part
printf("What is your first name? ");
fflush(stdin);
scanf("%29s", firstName); // wait new inputs and take not more than 29 characters
// asking for last part
printf("What is your last name? ");
fflush(stdin);
scanf("%29s", lastName); // wait new inputs and take up to 29 characters
// output result
printf("Your name is %s %s %s\n", firstName, middleInitial, lastName);
并尝试使用FGET而不是scanf。例如:

fflush(stdin);
fgets(firstName, 30, stdin); // this allows input of strings with spaces
// but adds 'new line' (\n) in the end of string
有关
fflush(stdin)
的建议是特定于平台的-有关更多信息,请参阅。
fflush(stdin);
fgets(firstName, 30, stdin); // this allows input of strings with spaces
// but adds 'new line' (\n) in the end of string