对于scanf(),为什么否定的扫描集"%[^n]"显示"n"的正确输出,而不是"aegis"的扫描集"%[aeiou]"?

For scanf(), why is negated scanset "%[^ ]" showing correct output for " ", but not the scanset "%[aeiou]" for "aegis"?

本文关键字:扫描 输出 aegis aeiou 显示 对于 为什么 scanf      更新时间:2023-10-16

在下面的程序中,如果我使用行作为被否定的扫描集,如果我输入一个多单词的行(以enter或换行结束),即使换行在被否定的列表中,它也能正常工作。

但是,如果我使用这行作为扫描集并输入单词"aegis"(或任何带有辅音的单词),则输出垃圾字符。与第一种情况类似,如果我输入这个单词,难道不应该至少输出"ae"吗?请解释scanf()的扫描集和反扫描集的行为。

#include <stdio.h>
int main ()
{
char str[30];
 printf("Enter the stringn");
 //scanf("%[^n]",str);
 //scanf("%[aeiou]",str);
 printf("%s",str);
}

这是因为代码错误地不检查scanf()的返回值

printf("Enter the stringn");
scanf("%[^n]",str);
scanf("%[aeiou]",str);  // check result before using `str`
printf("%s",str);

对于scanf("%[^n]",str);"123n"等输入,str得到"123" 的值,'n'留在stdin 中。然后使用scanf("%[aeiou]",str);和输入"aegisn",第一行的'n'块将任何内容保存为'n'不是元音,str中没有保存任何内容,并且由于代码没有检查scanf()的返回值,因此没有意识到str可能无效。

1)始终检查scanf()和family的返回值。

if (scanf(some_format, var1, var2, ...) != ExpectedConversionCount) {
  Fail();
}

2) scanf("%[^n]",str);读取一行失败3件事:没有输入限制,如果该行只包含'n',则无法读取任何内容。如果不检查返回值,则未检测到EOF

3)使用fgets()代替scanf()的用户输入