CC++ & Algorithm

C++字符串大小写转换

困难23
语言版本:C++Python
概述:学习如何将字符串中的字母转换为大写或小写,实现不区分大小写的比较。

把字母变大变小——C++字符串大小写转换

在写程序的时候,常常遇到这样的情况:用户输入了“abc”,但程序里存的是“ABC”;或者验证码明明是“Xy9”,有人却输入了“xY9”。作为程序,我们当然希望把它们当成一样的,不要因为大小写不同就报错。怎么做到呢?把字母全部变成大写,或者全部变成小写,再比较就行了!

C++ 里没有一句代码“刷”一下把整个字符串变大小写的函数,但我们可以用 循环 一颗颗“珍珠”(也就是每个字符)地处理。下面我们就来学习怎么做。


1. 准备工具:tolower()toupper()

这两个函数住在 <cctype> 这个头文件里(它专门负责处理字符,比如判断是不是字母、数字,转换大小写等)。用法很简单:

#include <cctype>   // 字符处理库

char ch = 'A';
char lower = tolower(ch);  // lower 变成 'a'
char upper = toupper('b'); // upper 变成 'B'

注意:这两个函数只对字母有效,如果传给它们数字、空格、标点符号,它们不会改变,原样返回。比如 toupper('1') 还是 '1'tolower('!') 还是 '!'


2. 把整个字符串的大小写一起转换

既然能转换单个字符,那用循环遍历字符串的每个字符就行啦。比如要把 "Hello World!" 全部变成大写:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string text = "Hello World!";   // 待转换的字符串
    for (int i = 0; i < text.length(); i++) {
        text[i] = toupper(text[i]); // 逐个变成大写
    }
    cout << text << endl;           // 输出 HELLO WORLD!
    return 0;
}

想变成小写,只要把 toupper 换成 tolower 就行:

for (int i = 0; i < text.length(); i++) {
    text[i] = tolower(text[i]); // 逐个变成小写
}

生活小例子:你有一个好友名单,里面全是小写字母,但用户可能输入大写的名字。你就可以先把输入的名字转成小写,再跟名单比较,这样大小写都不影响。


3. 不区分大小写的比较

有时候我们想比较两个字符串,但不想管大小写。一个简单的方法:先把两个字符串都转成相同的大小写(比如都转成小写),然后再用 == 比较。

比如判断用户名是否正确:

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string correctUser = "Alice";   // 正确的用户名(大小写混合)
    string inputUser;               // 用户输入
    cout << "请输入用户名:";
    cin >> inputUser;

    // 把两个字符串都转成小写再比较
    for (int i = 0; i < correctUser.length(); i++) correctUser[i] = tolower(correctUser[i]);
    for (int i = 0; i < inputUser.length(); i++) inputUser[i] = tolower(inputUser[i]);

    if (correctUser == inputUser) {
        cout << "用户名正确!" << endl;
    } else {
        cout << "用户名错误!" << endl;
    }
    return 0;
}

注意:这个例子里我们修改了 correctUserinputUser 原来的内容。如果你不想改原字符串,可以复制一份再处理。


4. 常见错误(新手容易踩的坑)

  • 忘记 #include <cctype>:要是没加这个头文件,touppertolower 会显示“未定义”,编译就会报错。
  • 循环边界写错:比如 for (int i = 0; i <= text.length(); i++),这会让 i 等于字符串长度时访问 text[text.length()],越界了!正确的条件是 i < text.length()
  • 对数字或符号使用 toupper:其实没问题,它们不会被改变,但新手可能会以为它们会被删除或报错——放心,原样不动。
  • 忘记引用命名空间:如果没写 using namespace std;,需要写成 std::toupperstd::tolower
  • 两个字符串长度不一样:如果两个字符串长度不同,比较结果肯定为 false。有时需要先转成相同大小写再比较长度——不过 == 运算符本身就能发现长度不同。

5. 完整示例——检查验证码(忽略大小写)

下面是一个完整的程序,模拟检查验证码的场景。用户输入的验证码不区分大小写,比如正确验证码是 "AbC9",用户输入 "abc9""ABC9" 都应该通过。

#include <iostream>
#include <string>
#include <cctype>
using namespace std;

int main() {
    string correct = "AbC9";        // 系统生成的正确验证码
    string guess;                   // 用户猜测的验证码
    cout << "请输入验证码(不区分大小写):";
    cin >> guess;

    // 将两个字符串都转成大写,方便比较
    for (int i = 0; i < correct.length(); i++) {
        correct[i] = toupper(correct[i]);  // 逐个变大写
    }
    for (int i = 0; i < guess.length(); i++) {
        guess[i] = toupper(guess[i]);      // 逐个变大写
    }

    if (correct == guess) {
        cout << "验证通过!" << endl;
    } else {
        cout << "验证码错误!" << endl;
    }
    return 0;
}

运行效果:

请输入验证码(不区分大小写):abc9
验证通过!

注意:验证码里可能有数字 9toupper('9') 还是 '9',不影响。


6. 更多小技巧:用 for(char &c : str) 遍历

C++11 之后可以用 范围 for 循环 来遍历字符串,更简洁:

string text = "Hello World!";
for (char &c : text) {      // c 是 text 中每个字符的引用
    c = toupper(c);         // 直接修改原字符
}
// 现在 text 是 "HELLO WORLD!"

这个写法不用操心下标,不容易出错,推荐使用。


7. 相关指引

学会了大小写转换,接下来可以看看:

  • 字符串的更多操作:比如查找子串、替换子串、拼接等(string::find, string::replace, + 运算符)。
  • 字符判断函数<cctype> 里还有 isalpha()(判断字母)、isdigit()(判断数字)、isupper()(判断大写)、islower()(判断小写)等。这些在过滤字符时很有用。
  • 忽略大小写的比较另一种方法:可以自己写一个函数,比较两个字符时都转成小写再比较,这样不用事先修改整个字符串。

练习一下:写一个程序,输入一句英文,把其中所有大写字母转成小写,所有小写字母转成大写(其他字符不变),然后输出。试试看吧!

例题精讲

1单选题

在C++中,将字符串"Hello World"中的所有小写字母转换为大写字母,以下哪种方法最简洁且高效?

A使用for循环遍历每个字符,调用toupper()
B使用std::transform配合std::toupper
C使用std::string::toupper成员函数
D使用std::upper_case函数
2判断题

C++标准库中的std::string类提供了直接转换整个字符串为小写的成员函数toLower()。

3填空题
以下代码使用std::transform将字符串s转换为大写,请填空。
#include <algorithm>
#include <cctype>
#include <string>
std::string s = "hello";
std::transform(s.begin(), s.end(), s.begin(), ___);
4单选题

在ASCII码中,小写字母'a'和对应大写字母'A'的差值是多少?

A32
B64
C16
D0
5填空题
以下代码手动实现了将字符串str中所有大写字母转换为小写字母,请填空。
for (char &c : str) {
    if (c >= 'A' && c <= 'Z')
        c = c + ___;
}