BC15 大小写转换 完整解析
一、题目核心解读
这道题的核心考点有三个:
- 字母大小写的 ASCII 码转换原理
- 多组输入循环处理
%c读取字符的换行缓冲区坑(题目备注专门提示了这个点)
题目要求:循环读取多组大写字母,每行一个,转换成对应的小写字母输出。
二、核心知识点
1. 大小写转换原理
在 ASCII 码表中:
- 大写字母
A-Z对应码值65-90 - 小写字母
a-z对应码值97-122
同一个字母的大小写,ASCII 码值相差 32 。因此大写字母 + 32 就能得到对应的小写字母。
更规范的写法:
ch = ch - 'A' + 'a',不依赖具体 ASCII 数值,可移植性更好。
2. 多组输入
OJ 的多组输入会持续给入数据,直到输入结束(文件末尾 EOF)。 scanf() 的返回值是成功读取的变量个数,读到末尾时返回 EOF,因此用 while(scanf(...) != EOF) 实现循环。
3. 换行符的坑(题目备注重点)
%c 不会自动跳过空白字符,空格、回车、Tab 都会被当成一个字符读入 。 输入 A 然后按回车,缓冲区里是 'A' + '\n':
- 第一次
%c读到'A' - 第二次
%c会读到换行符'\n',导致转换出错
三、完整 AC 代码(推荐写法,最简洁稳妥)
#include <stdio.h>
int main() {
char ch;
// %c 前面加一个空格:自动跳过所有空白(换行、空格、Tab)
while (scanf(" %c", &ch) != EOF) {
// 大写转小写:ASCII码 +32
printf("%c\n", ch + 32);
}
return 0;
}
逐段拆解
1. while ( ... != EOF ) ------ 多组输入循环框架
while (scanf(" %c", &ch) != EOF)
scanf()是有返回值的:成功读取到几个变量,就返回对应的数字;如果读到输入末尾(没有更多数据了) ,就返回EOF(End Of File,本质是整数-1)。- 含义:只要还能成功读到有效字符,循环就一直执行;输入读完了,循环自动结束。
四、逐行原理详解
1. 关键:" %c" 前面的空格
scanf(" %c", &ch)
格式串里 %c 前面的空格,作用是:读取字符前,先跳过输入中任意数量的空白字符(空格、换行、制表符) ,直接读取下一个非空白的有效字符。 这是解决换行缓冲区问题最简单、最通用的方法,比手动 getchar() 更鲁棒。
2. 转换逻辑
ch + 32
例如输入 'A'(ASCII 65),65 + 32 = 97,对应字符 'a'。
等价写法(更规范):
ch - 'A' + 'a'用字符本身做运算,不依赖具体 ASCII 码值,可读性更强。
3. 多组循环
while (scanf(" %c", &ch) != EOF)
只要还能读到有效字符,循环就继续;读到输入末尾,scanf 返回 EOF,循环结束。 完全匹配 OJ 多组输入的判题机制。
五、对应备注的另一种写法(手动吸收回车)
题目备注提示 "用 getchar() 吸收回车",写法如下:
#include <stdio.h>
int main() {
char ch;
while (scanf("%c", &ch) != EOF) {
// 如果读到的是换行符,跳过不处理
if (ch == '\n') {
continue;
}
printf("%c\n", ch + 32);
}
return 0;
}
缺点:只能处理换行,如果输入有空格、Tab 还是会出错。 刷题优先推荐第一种
" %c"的写法。
- 冲区坑(题目备注专门提示了这个点)