我刚刚开始学习C。这是我正在试验的一些示例代码。它只是为了获取用户名。如果我为第一个需要字符的答案输入一个字符串,第一个字母将保存到middleInitial,但随后的扫描会读取并保存字符串的其余部分,而不是忽略其余部分。这意味着输入"Jacob"然后输入"Pat Smith"将导致输出"你的名字是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);
我对 C 中的字符串 (char*) 用法有一些建议。首先,正如 sumithdev 所说,在输入任何信息之前,使用 fflush(stdin) 清理输入流缓冲区。其次,尝试使用统一的样式来存储所有字符串数据。例如,你的 middleInitial 也可以定义为 char 数组,但长度可能为 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 %sn", firstName, middleInitial, lastName);
并且还尝试使用 fgets 而不是 scanf。例如:
fflush(stdin);
fgets(firstName, 30, stdin); // this allows input of strings with spaces
// but adds 'new line' (n) in the end of string
根据代码:
scanf(" %c", &middleInitial);
middleInitial获取输入的唯一第一个字符。
例如:yout 输入"Jacob",然后输入"John Smith":
middleInitial = J
firstName = acob
lastName = John
您应该尝试:
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);
原因是第一个scanf
未获取的剩余字符保留在STDIN
缓冲区中,然后由后续scanf
影响。 在阅读firstname
和lastname
之前flush
STDIN。由于fflush
不是删除 STDIN 缓冲区中不需要的字符的可靠方法,因此此处介绍了手动操作方法。