user-0 提问: 关于%s的一个问题

回复:
user: user-1
content: Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

user: user-2
content: scanf("%s%s", ch1, ch2);   你会发现使用空格分割输入或者使用回车分割输入都是一样的  只有 %s 才能这样！

user: user-2
content: 修改答案  ---  是 %s 不会读取空格，也就是说遇到空格结束读取，如果遇到回车则忽略  若 %c 则会读取到回车

user: user-2
content: b读入换行符然后输出空格 > 为什么会输出空格呢？不应该输出回车吗？  scanf 不会读取空格，也就是说遇到空格结束读取，  所以   %s 消耗 "ac"  %c 消耗 " "  %c 消耗 "c"   所以 printf 打印 "c"

user: user-0
content: 引用 3 楼 提及 的回复:原理？？？  你需要什么样的原理  这是别人设计好的  因为字符串就是最后一个元素为 \0 的字符数组  回车键是用来结束输入的  使用 %s 遇到回车结束输入，回车不做为结果，回车符保存在输入缓冲区，等待下一次读取 并且在输入的字符串后面追加 \0  > 只有字符数组最后一个元素是 \0 才能将其称作字符串，否则就是字符数组  所以在使用的时候，就需要填写 <数组大小-1> 的最大域宽，做好安全工作   如果你想使用 %s 将读取的内容作为字符数组的话，不可以  但你可以使用 %<number>c  将读取的内容作为字符数组。只需限定域宽，不会追加 \0不好意思，之前那个测试函数不用看了我傻了。。 其实问题的起因是我看到一段代码这样实现了一个由字符组成地图的输入,但是现在原理我是清楚了但是还是不懂下面这段为啥不用getchar掉换行符                 char map[2][12][12] ; 		for (i=0; i<2; i++)  			for (j=0; j<12; j++)  				scanf("%s", map[i][j]);

user: user-0
content: 引用 3 楼 提及 的回复:原理？？？  你需要什么样的原理  这是别人设计好的  因为字符串就是最后一个元素为 \0 的字符数组  回车键是用来结束输入的  使用 %s 遇到回车结束输入，回车不做为结果，回车符保存在输入缓冲区，等待下一次读取 并且在输入的字符串后面追加 将其需要填写 <数组大小-1> 的最大域宽， 如果你想使用 %s 将读取的内容作为字符数组的话，不可以 组。只需限定域宽，不会追加 \0 quote]  [quote=引用 3 楼 提及 的回复:] 原理？？？  你需要什么样的原理  这是别人设计好的  因为字符串就是最后一个元素为 \0 的字符数组  回车键是用来结束输入的  使用 %s 遇到回车结束输入，回车不做为结果，回车符保存在输入缓冲区，等待下一次读取 并且在输入的字符串后面追加 \0  > 只有字符数组最后一个元素是 \0 才能将其称作字符串，否则就是字符数组  所以在使用的时候，就需要填写 <数组大小-1> 的最大域宽，做好安全工作   如果你想使用 %s 将读取的内容作为字符数组的话，不可以  但你可以使用 %<number>c  将读取的内容作为字符数组。只需限定域宽，不会追加 \0那请问下面这段简单的代码 我输入ac c为啥是输出c呢 按道理不应该b读入换行符然后输出空格吗 #include <iostream> #include <stdio.h> using namespace std;  int main() {   char a[50],b;     scanf("%s",a);     scanf("%c",&b);     b=getchar();     printf("%c",b);     return 0; }

user: user-3
content: 标准输入是属于行缓冲的，因此需要输入回车才能将输入的内容刷到内存（在这之前是输入的内容在输入缓存里）

user: user-0
content: 引用 1 楼 提及的回复:自己测试一下不就知道了   我自己试过了换行符貌似它直接帮你去掉了，但是不清楚原理

user: user-2
content: 原理？？？  你需要什么样的原理  这是别人设计好的  因为字符串就是最后一个元素为 \0 的字符数组  回车键是用来结束输入的  使用 %s 遇到回车结束输入，回车不做为结果，回车符保存在输入缓冲区，等待下一次读取 并且在输入的字符串后面追加 \0  > 只有字符数组最后一个元素是 \0 才能将其称作字符串，否则就是字符数组  所以在使用的时候，就需要填写 <数组大小-1> 的最大域宽，做好安全工作   如果你想使用 %s 将读取的内容作为字符数组的话，不可以  但你可以使用 %<number>c  将读取的内容作为字符数组。只需限定域宽，不会追加 \0

user: user-2
content: 自己测试一下不就知道了