有人能就scanf提出建议吗?“message”是4行乘16列的数组。用户输入数字(均为1位整数)后,点击“Enter”时出现错误消息。就像我说的-可能是scanf的问题。
for (int i = 0; i < M; i++) { for (int j = 0; j < columns; j++) { scanf("%d", message[i][j]); } }
wnavrhmk1#
scanf * 看起来 * 是一个很好的、简单的、容易的、方便的读取输入的方法。在某些方面,它是,但事实证明,正确使用它可以是惊人的困难,它充满了陷阱。您可能不想一开始就了解scanf的所有复杂性。现在,这里有一些安全使用scanf功能 * 子集 * 的指南。(由于我不明白的原因,每个人都告诉初学者使用scanf,但没有人教过这样沿着规则。)1.请记住,在要读取的变量前面始终使用&。(这是一个特殊的规则,仅适用于scanf。例如,不要尝试在传递给printf的变量上使用&。)1.规则1的例外:当你用%s阅读字符串时,不要 * 使用&。1.如果你使用%s阅读字符串,请确保你读入的变量是一个足够大的字符数组,以容纳用户可能要输入的内容,或者是一个指向艾德的指针,该指针足够大,以容纳用户可能要输入的内容。(另请参阅下面关于避免溢出的说明。)1.注意%s读取的字符串 * 不 * 包含空格字符。不能使用%s读取可能包含空格的字符串(如全名)。(现在,请不要担心如何读取可能包含空格的字符串。另见规则14。)1.不要试图在同一个程序中同时使用scanf和fgets(或过时的gets)。1.不要试图在同一个程序中同时使用scanf和getchar。1.尝试只使用格式说明符%d、%s、%f和%lf,分别读入int、string(参见规则3)、float和double类型的变量。1.如果你想把一个字符读入一个char类型的变量,你可以使用" %c",但神秘的额外显式空格字符是至关重要的。1.在格式字符串中只使用一个%符号,以读取一个变量。不要尝试在一个scanf调用中读取两个或更多变量。1.始终检查scanf的返回值。如果它返回0或负值EOF,这意味着它没有成功读取任何内容。如果它返回1,则意味着它成功读取了一个值。(如果你违反了规则9,并试图读取多个值,它将返回它成功读取的值的数量,介于0和你要求的数量之间。)1.如果scanf返回0或EOF,表明用户没有键入有效值,则只需打印错误消息并退出。不要尝试编写要求用户再试一次的代码,因为用户的错误输入仍然停留在输入流中,并且没有好的、简单的方法来消除它。(如果您真的想编写用户友好的代码,在出现错误时重新提示,scanf不是完成这项工作的合适工具。)1.永远不要在格式字符串后面放空格。其中包括换行符\n。(也就是说,使用"%d",而不是"%d "或"%d\n"。)1.不要尝试使用%[…]说明符。1.如果你违反了规则13(也许是因为有人告诉你%[…]可能是一种读取包含空格的字符串或整行的方法),不要在它后面加上s。格式是%[…],而不是%[…]s。这些规则可能看起来很有限制性,* 但是 * 如果你遵循这些规则,你应该能够简单,容易和可靠地将简单的输入输入到你的简单程序中,这就是这里的目标。scanf在其他方面非常难以使用,经验表明,有17种不同的可怕的令人沮丧的问题往往会出现,试图解决它们是完全不必要的,会分散你通过编写简单的C程序来学习C的目标。当你阅读%s或%[…]的字符串时,有一个危险:无论你阅读的数组或malloc '艾德缓冲区有多大,用户输入的可能都不止这些。为了避免溢出,可以使用%19s这样的格式来显式地告诉scanf允许读取多少字符。(请记住减去1,为终止'\0'留出空间。也就是说,您可以使用%19s读入char str[20];或char *p = malloc(20);。)这些规则多少有些多。有关更简单的规则集,请参阅此答案。将规则7、8、9、12和13放在一起,实际上只有五个完整的格式字符串你想与scanf一起使用:"%d"、"%s"、"%f"、"%lf"或" %c"。(但是没有逗号,没有固定字符串,除了" %c"中的显式空格之外没有空格,没有其他。)例外情况:如上所述,使用%19s之类的东西来限制正在读取的字符串的长度是很好的。如果你需要做一些更复杂的事情,而你不能在这些规则内完成,那么是时候:
scanf
&
printf
%s
fgets
gets
getchar
%d
%f
%lf
int
float
double
char
" %c"
%
EOF
\n
"%d"
"%d "
"%d\n"
%[…]
s
%[…]s
malloc
%19s
'\0'
char str[20];
char *p = malloc(20);
"%s"
"%f"
"%lf"
1.充分了解scanf是如何工作的(和不工作的),这样你就可以尝试做你想做的事情,但不会陷入这17个问题中的任何一个,或者1.学习如何使用better and more powerful methods than scanf进行输入,可能是通过使用fgets阅读整行,然后解析它们。
ki1q1bka2#
“message[i][j]"前缺少“&”。
for (int i = 0; i < M; i++) { for (int j = 0; j < columns; j++) { scanf("%d", &message[i][j]); } }
2条答案
按热度按时间wnavrhmk1#
scanf
* 看起来 * 是一个很好的、简单的、容易的、方便的读取输入的方法。在某些方面,它是,但事实证明,正确使用它可以是惊人的困难,它充满了陷阱。您可能不想一开始就了解
scanf
的所有复杂性。现在,这里有一些安全使用scanf
功能 * 子集 * 的指南。(由于我不明白的原因,每个人都告诉初学者使用scanf
,但没有人教过这样沿着规则。)1.请记住,在要读取的变量前面始终使用
&
。(这是一个特殊的规则,仅适用于scanf
。例如,不要尝试在传递给printf
的变量上使用&
。)1.规则1的例外:当你用
%s
阅读字符串时,不要 * 使用&
。1.如果你使用
%s
阅读字符串,请确保你读入的变量是一个足够大的字符数组,以容纳用户可能要输入的内容,或者是一个指向艾德的指针,该指针足够大,以容纳用户可能要输入的内容。(另请参阅下面关于避免溢出的说明。)1.注意
%s
读取的字符串 * 不 * 包含空格字符。不能使用%s
读取可能包含空格的字符串(如全名)。(现在,请不要担心如何读取可能包含空格的字符串。另见规则14。)1.不要试图在同一个程序中同时使用
scanf
和fgets
(或过时的gets
)。1.不要试图在同一个程序中同时使用
scanf
和getchar
。1.尝试只使用格式说明符
%d
、%s
、%f
和%lf
,分别读入int
、string(参见规则3)、float
和double
类型的变量。1.如果你想把一个字符读入一个
char
类型的变量,你可以使用" %c"
,但神秘的额外显式空格字符是至关重要的。1.在格式字符串中只使用一个
%
符号,以读取一个变量。不要尝试在一个scanf
调用中读取两个或更多变量。1.始终检查
scanf
的返回值。如果它返回0或负值EOF
,这意味着它没有成功读取任何内容。如果它返回1,则意味着它成功读取了一个值。(如果你违反了规则9,并试图读取多个值,它将返回它成功读取的值的数量,介于0和你要求的数量之间。)1.如果
scanf
返回0或EOF
,表明用户没有键入有效值,则只需打印错误消息并退出。不要尝试编写要求用户再试一次的代码,因为用户的错误输入仍然停留在输入流中,并且没有好的、简单的方法来消除它。(如果您真的想编写用户友好的代码,在出现错误时重新提示,scanf
不是完成这项工作的合适工具。)1.永远不要在格式字符串后面放空格。其中包括换行符
\n
。(也就是说,使用"%d"
,而不是"%d "
或"%d\n"
。)1.不要尝试使用
%[…]
说明符。1.如果你违反了规则13(也许是因为有人告诉你
%[…]
可能是一种读取包含空格的字符串或整行的方法),不要在它后面加上s
。格式是%[…]
,而不是%[…]s
。这些规则可能看起来很有限制性,* 但是 * 如果你遵循这些规则,你应该能够简单,容易和可靠地将简单的输入输入到你的简单程序中,这就是这里的目标。
scanf
在其他方面非常难以使用,经验表明,有17种不同的可怕的令人沮丧的问题往往会出现,试图解决它们是完全不必要的,会分散你通过编写简单的C程序来学习C的目标。当你阅读
%s
或%[…]
的字符串时,有一个危险:无论你阅读的数组或malloc
'艾德缓冲区有多大,用户输入的可能都不止这些。为了避免溢出,可以使用%19s
这样的格式来显式地告诉scanf
允许读取多少字符。(请记住减去1,为终止'\0'
留出空间。也就是说,您可以使用%19s
读入char str[20];
或char *p = malloc(20);
。)这些规则多少有些多。有关更简单的规则集,请参阅此答案。将规则7、8、9、12和13放在一起,实际上只有五个完整的格式字符串你想与
scanf
一起使用:"%d"
、"%s"
、"%f"
、"%lf"
或" %c"
。(但是没有逗号,没有固定字符串,除了" %c"
中的显式空格之外没有空格,没有其他。)例外情况:如上所述,使用%19s
之类的东西来限制正在读取的字符串的长度是很好的。如果你需要做一些更复杂的事情,而你不能在这些规则内完成,那么是时候:
1.充分了解
scanf
是如何工作的(和不工作的),这样你就可以尝试做你想做的事情,但不会陷入这17个问题中的任何一个,或者1.学习如何使用better and more powerful methods than
scanf
进行输入,可能是通过使用fgets
阅读整行,然后解析它们。ki1q1bka2#
“message[i][j]"前缺少“&”。