用 %c 或 %s 扫描 [英] Scanning with %c or %s
问题描述
我必须为大学做一个计划,在该计划中,我应该将一定数量的人区分喜欢和不喜欢某事的人.所以我这样做了:
I had to do a program for college in which I should separate, between a certain amount of people, those who liked and the ones who disliked something. so I did this:
char like[100];
printf("Like? Y or N \n");
scanf ("%c", like);
程序已编译,但未按应有的方式运行.当被问到喜欢?"时,用户无法写出y 或 n"
The program compiled, but didn't work the way it should. The user was not able to write "y or n" when asked "Like?"
所以我尝试了这个:
char like[100];
printf("Like? Y or N \n");
scanf ("%s", like);
它奏效了.但我不知道它为什么起作用.有人可以解释一下 %c
和 %s
在 scanf
中的区别吗?
And it worked. But I don't know why it worked. Can somebody please explain me the difference between %c
and %s
in a scanf
?
推荐答案
首先,请在来这里之前做一些基础研究 - 像这样的问题通常可以通过快速的 Google 搜索或查看您方便的 C 参考手册来回答.
First, please do some basic research before coming here - questions like this can usually be answered with a quick Google search or checking your handy C reference manual.
char inputChar; // stores a single character
char inputString[100] = {0}; // stores a string up to 99 characters long
scanf( " %c", &inputChar ); // read the next non-whitespace character into inputChar
// ^ Note & operator in expression
scanf( "%s", inputString ); // read the next *sequence* of non-whitespace characters into inputString
// ^ Note no & operator in expression
当您想从输入流中读取单个字符并将其存储到char
对象时,您可以使用%c
.%c
转换说明符不会跳过任何前导空格,因此如果您想读取下一个 非 空格字符,则需要在 % 之前留一个空格格式字符串中的 c
说明符,如上所示.
You would use %c
when you want to read a single character from the input stream and store it to a char
object. The %c
conversion specifier will not skip over any leading whitespace, so if you want to read the next non-whitespace character, you need a blank before the %c
specifier in your format string, as shown above.
当您想从输入流中读取非空白字符的序列并将它们存储到数组%s> char
.您的目标数组必须足够大以存储输入字符串加上一个终止的 0 值字符.%s
转换说明符跳过任何前导空格并在非空格字符之后的第一个空格字符处停止读取.
You would use %s
when you want to read a sequence of non-whitespace characters from the input stream and store them to an array of char
. Your target array must be large enough to store the input string plus a terminating 0-valued character. The %s
conversion specifier skips over any leading whitespace and stops reading at the first whitespace character following the non-whitespace characters.
%c
和 %s
都期望它们对应的参数具有 char *
类型(指向 char
);然而,在第一种情况下,假设指针指向单个对象,而在第二种情况下,假设指针指向数组的第一个元素.对于inputChar
,我们必须使用一元&
运算符来获取指针值.对于inputString
,我们不会,因为在大多数情况下,类型为T
数组"的表达式将被转换(衰减")类型为指向 T
的指针"的表达式,表达式的值将是数组第一个元素的地址.
Both %c
and %s
expect their corresponding argument to have type char *
(pointer to char
); however, in the first case, it's assumed that the pointer points to a single object, whereas in the second case, it's assumed that the pointer points to the first element of an array. For inputChar
, we must use the unary &
operator to obtain the pointer value. For inputString
, we don't, because under most circumstances an expression of type "array of T
" will be converted ("decay") to an expression of type "pointer to T
", and the value of the expression will be the address of the first element of the array.
您的代码可以正常工作,但读取单个字符并将其存储到数组中有点混乱.
Your code works fine as it is, but it's a bit confusing to read a single character and store it to an array.
在没有明确字段宽度的情况下使用 %s
是有风险的;如果有人输入超过 100 个非空白字符,scanf
会很乐意将这些额外的字符存储到 inputString
之后的内存中,这可能会破坏一些重要的东西.写这样的东西通常更安全
Using %s
without an explicit field width is risky; if someone types in more than 100 non-whitespace characters, scanf
will happily store those extra characters to memory following inputString
, potentially clobbering something important. It's generally safer to write something like
scanf( "%99s", inputString ); // reads no more than 99 characters into inputString
或者使用 fgets()
来读取输入字符串:
or to use fgets()
to read input strings instead:
fgets( inputString, sizeof inputString, stdin );
请检查的§7.21.6.2C 语言标准的在线草案 完整描述了 *scanf
函数的所有转换说明符.
Please check §7.21.6.2 of the online draft of the C language standard for a complete description of all of the conversion specifiers for the *scanf
functions.
这篇关于用 %c 或 %s 扫描的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!