scanf()中scanset工作原理解析:为何实际输出与预期不符?
关于scanf scanset工作机制的误解与解决方法
你确实误解了scanf中%[格式符(即scanset)的工作逻辑。
scanset的实际行为
%[A-Z]这类scanset格式符的作用是:从输入流中连续读取匹配指定字符集合的字符,直到遇到第一个不匹配的字符、输入结束或者达到长度限制时停止。它不会跳过不匹配的字符去读取后续的匹配字符,而是直接终止读取操作。
你的输入HeLlO中,第一个字符H属于A-Z范围,会被读取;第二个字符e是小写字母,不在指定集合内,scanf立刻停止读取,所以str中只存入了H,加上自动添加的字符串终止符\0,最终输出就是H。
另外你的代码里还有个小错误:格式字符串"%[A-Z]s"中的s是多余的。%[本身就是完整的格式说明符,后面的s会被当作普通字符要求匹配,不过在这个例子里因为提前遇到了不匹配的e,所以这个错误没表现出来,正确的写法应该是"%[A-Z]"。
实现“过滤保留匹配字符”的方法
如果想要遍历整个输入字符串,只保留符合A-Z的字符,scanf的scanset做不到,需要手动逐个处理字符,示例代码如下:
#include <stdio.h> #include <ctype.h> int main(void) { char str[128]; int c; int idx = 0; printf("Enter a string: "); // 循环读取字符,直到换行、EOF或者数组满 while ((c = getchar()) != EOF && c != '\n' && idx < 127) { if (isupper(c)) { // 判断是否为大写字母 str[idx++] = c; } } str[idx] = '\0'; // 手动添加字符串终止符 printf("You entered: %s\n", str); return 0; }
这段代码会逐个读取输入的每个字符,只把大写字母存入数组,输入HeLlO时就会输出HLO,符合你的预期。
内容的提问来源于stack exchange,提问作者Sandrious
相关产品推荐
相关产品推荐

