1.字符型 2.字符串基础 3.字符串进阶

登录以参加训练计划

C++ 字符串处理全面指南 - CSP-J 核心知识点

面向10-14岁学生,结合CSP-J考纲整理的字符串处理知识点

目录

  1. 字符型基础
  2. 字符串基础操作
  3. 字符串进阶应用
  4. 字符串处理技巧
  5. 常见问题解析

1. 字符型基础

字符的本质

字符是编程中的基本单位,每个字符对应一个ASCII码值

#include <iostream>
using namespace std;

int main() {
    char c = 'A'; // 字符用单引号
    
    // 输出字符及其ASCII码
    cout << "字符: " << c << endl;
    cout << "ASCII码: " << (int)c << endl; // 输出65
    
    // 字符运算
    char c2 = c + 1; // 'B'
    cout << "下一个字符: " << c2 << endl;
    
    // 大小写转换
    char lower = 'b';
    char upper = lower - 32; // 'B'
    cout << lower << " → " << upper << endl;
    
    return 0;
}

ASCII码表摘要

字符类型 ASCII范围 示例
数字字符 48-57 '0'=48, '9'=57
大写字母 65-90 'A'=65, 'Z'=90
小写字母 97-122 'a'=97, 'z'=122
特殊字符 32-47, 58-64 空格=32, '@'=64

字符处理函数

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

char c = 'a';
isalpha(c); // 是否是字母 → true
isdigit(c); // 是否是数字 → false
islower(c); // 是否小写 → true
toupper(c); // 转大写 → 'A'
tolower('B'); // 转小写 → 'b'
isspace(' '); // 是否空白 → true

2. 字符串基础操作

两种字符串表示

// 1. C风格字符串(字符数组)
char str1[10] = "Hello"; // 自动添加'\0'

// 2. C++ string类
#include <string>
string str2 = "World";

C风格字符串基础

#include <iostream>
#include <cstring> // 字符串函数库
using namespace std;

int main() {
    char name[20];
    
    // 安全输入
    cout << "请输入姓名: ";
    cin.getline(name, 20); // 避免溢出
    
    // 字符串长度
    int len = strlen(name);
    cout << "长度: " << len << endl;
    
    // 字符串复制
    char copy[20];
    strcpy(copy, name);
    cout << "复制: " << copy << endl;
    
    // 字符串连接
    strcat(copy, "!");
    cout << "连接后: " << copy << endl;
    
    // 字符串比较
    if (strcmp(name, "Alice") == 0) {
        cout << "你好, Alice!" << endl;
    }
    
    return 0;
}

string类基础操作

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

int main() {
    string s1 = "Hello";
    string s2 = "C++";
    
    // 字符串连接
    string s3 = s1 + " " + s2 + "!";
    cout << s3 << endl; // Hello C++!
    
    // 字符串长度
    cout << "长度: " << s3.length() << endl; // 10
    
    // 字符串比较
    if (s1 == "Hello") {
        cout << "相等" << endl;
    }
    
    // 子串提取
    string sub = s3.substr(6, 3); // 从位置6开始取3个字符
    cout << "子串: " << sub << endl; // C++
    
    // 查找子串
    int pos = s3.find("C++");
    if (pos != string::npos) {
        cout << "找到C++位置: " << pos << endl; // 6
    }
    
    return 0;
}

字符串输入输出对比

操作 C风格字符串 string类
声明 char str[20]; string str;
输入 cin.getline(str,20); getline(cin, str);
输出 cout << str;
长度 strlen(str) str.length()
复制 strcpy(dest,src); dest = src;
连接 strcat(str1,str2); str1 + str2
比较 strcmp(str1,str2)==0 str1 == str2

3. 字符串进阶应用

3.1 字符串转换

#include <iostream>
#include <string>
#include <cctype> // 字符处理
#include <cstdlib> // 数值转换
using namespace std;

int main() {
    // 字符串 → 整数
    string numStr = "123";
    int num = stoi(numStr); // C++11
    cout << "数值: " << num * 2 << endl; // 246
    
    // 整数 → 字符串
    int value = 456;
    string strVal = to_string(value);
    cout << "字符串: " << strVal + "!!" << endl; // 456!!
    
    // 大小写转换
    string text = "Hello World";
    for (char &c : text) { // 引用修改
        c = toupper(c);
    }
    cout << "大写: " << text << endl; // HELLO WORLD
    
    return 0;
}

3.2 字符串分割

#include <iostream>
#include <string>
#include <vector>
#include <sstream> // 字符串流
using namespace std;

int main() {
    string data = "apple,banana,orange,grape";
    
    // 方法1:使用字符串流
    vector<string> fruits;
    stringstream ss(data);
    string item;
    
    while (getline(ss, item, ',')) {
        fruits.push_back(item);
    }
    
    cout << "分割结果:" << endl;
    for (const string& fruit : fruits) {
        cout << "- " << fruit << endl;
    }
    
    return 0;
}

3.3 字符串匹配

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

int main() {
    string text = "CSP-J竞赛是全国青少年信息学奥林匹克竞赛的重要组成部分";
    string pattern = "青少年";
    
    // 简单匹配算法
    int tLen = text.length();
    int pLen = pattern.length();
    
    for (int i = 0; i <= tLen - pLen; i++) {
        bool match = true;
        for (int j = 0; j < pLen; j++) {
            if (text[i+j] != pattern[j]) {
                match = false;
                break;
            }
        }
        if (match) {
            cout << "在位置 " << i << " 找到匹配" << endl;
        }
    }
    
    return 0;
}

3.4 字符串加密

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

int main() {
    string plain = "Hello CSP-J!";
    string cipher = "";
    
    // 凯撒加密(偏移3位)
    for (char c : plain) {
        if (isalpha(c)) {
            char base = islower(c) ? 'a' : 'A';
            c = ((c - base + 3) % 26) + base;
        }
        cipher += c;
    }
    
    cout << "加密后: " << cipher << endl; // Khoor FVS-M!
    
    return 0;
}

4. 字符串处理技巧

4.1 常见处理模式

// 1. 遍历字符串
string str = "Hello";
for (int i = 0; i < str.length(); i++) {
    cout << str[i];
}

// 2. 范围遍历(C++11)
for (char c : str) {
    cout << c;
}

// 3. 删除字符
str.erase(remove(str.begin(), str.end(), 'l'), str.end());
// 删除所有'l' → "Heo"

// 4. 反转字符串
reverse(str.begin(), str.end());
// "olleH"

// 5. 去首尾空格
string s = "  text  ";
s.erase(0, s.find_first_not_of(' ')); // 去首空格
s.erase(s.find_last_not_of(' ') + 1); // 去尾空格

4.2 字符串算法模板

// 判断回文字符串
bool isPalindrome(string s) {
    int left = 0, right = s.length()-1;
    while (left < right) {
        if (s[left++] != s[right--]) 
            return false;
    }
    return true;
}

// 统计字符出现次数
void countChars(string s) {
    int count[256] = {0}; // ASCII字符统计
    
    for (char c : s) {
        count[c]++;
    }
    
    for (int i = 0; i < 256; i++) {
        if (count[i] > 0) {
            cout << (char)i << ": " << count[i] << endl;
        }
    }
}

// 字符串替换
string replaceAll(string str, string from, string to) {
    size_t pos = 0;
    while ((pos = str.find(from, pos)) != string::npos) {
        str.replace(pos, from.length(), to);
        pos += to.length();
    }
    return str;
}

4.3 字符串处理综合应用

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

int main() {
    string input;
    cout << "请输入英文句子: ";
    getline(cin, input);
    
    // 1. 转换为小写
    transform(input.begin(), input.end(), input.begin(), ::tolower);
    
    // 2. 移除标点
    input.erase(remove_if(input.begin(), input.end(), ::ispunct), input.end());
    
    // 3. 单词计数
    stringstream ss(input);
    string word;
    int wordCount = 0;
    
    while (ss >> word) {
        wordCount++;
    }
    
    cout << "单词数量: " << wordCount << endl;
    
    // 4. 最长单词
    ss.clear();
    ss.str(input);
    string longest = "";
    
    while (ss >> word) {
        if (word.length() > longest.length()) {
            longest = word;
        }
    }
    
    cout << "最长单词: " << longest << endl;
    
    return 0;
}

5. 常见问题解析

5.1 字符串输入陷阱

// 错误示例
int age;
string name;

cout << "输入年龄: ";
cin >> age;
cout << "输入姓名: ";
getline(cin, name); // 会跳过输入!

// 原因:cin>>后遗留换行符
// 解决方法:
cin.ignore(); // 清除输入缓冲区
getline(cin, name);

5.2 内存溢出问题

// C风格字符串常见错误
char str[5];
strcpy(str, "HelloWorld"); // 溢出!

// 安全方法:
strncpy(str, "Hello", 4); // 最多复制4字符
str[4] = '\0'; // 确保结束符

5.3 字符串比较误区

// 错误比较
char s1[10] = "hello";
char s2[10] = "hello";
if (s1 == s2) { // 比较地址而非内容!
    // 永远不会执行
}

// 正确比较:
if (strcmp(s1, s2) == 0) { // C风格
    // ...
}

string s3 = "hello";
string s4 = "hello";
if (s3 == s4) { // string类可直接比较
    // ...
}

5.4 性能优化建议

  1. 减少临时字符串:避免不必要的字符串复制

    // 低效
    string result = str1 + str2 + str3;
    
    // 高效
    string result;
    result.reserve(str1.size() + str2.size() + str3.size()); // 预分配空间
    result = str1;
    result += str2;
    result += str3;
    
  2. 使用引用传递:函数参数使用const引用

    void process(const string& str) { // 避免复制
        // ...
    }
    
  3. 移动语义(C++11):对于临时字符串

    string createString() {
        string s = "大字符串";
        return s; // 使用移动而非复制
    }
    

字符串处理总结表

知识点 关键内容 应用场景
字符基础 ASCII码、字符函数 字符转换、验证
C风格字符串 字符数组、'\0'结尾 底层操作、兼容C
string类 长度可变、操作丰富 日常开发、复杂处理
字符串转换 stoi/to_string 数据格式转换
字符串分割 stringstream 解析CSV等数据
字符串匹配 简单匹配/KMP算法 文本搜索
加密处理 凯撒密码、位运算 数据安全

学习建议

  1. 掌握字符与ASCII码的关系
  2. 理解C风格字符串与string类的区别
  3. 熟练使用string类的常用方法
  4. 练习常见字符串算法(反转、分割、匹配)
  5. 注意字符串输入输出的常见陷阱

"字符串处理是编程的基石,掌握它等于掌握了文本世界的钥匙!"

字符串处理能力自测

  1. 如何统计字符串中数字字符的数量?
  2. 如何判断字符串是否为回文?
  3. 如何将字符串按单词反转("Hello World" → "World Hello")?
  4. 如何实现字符串的简单加密和解密?
  5. 如何高效拼接多个字符串?

综合练习:单词分析器

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

int main() {
    string text;
    cout << "输入英文文本: ";
    getline(cin, text);
    
    // 转换为小写
    transform(text.begin(), text.end(), text.begin(), ::tolower);
    
    // 移除标点
    text.erase(remove_if(text.begin(), text.end(), ::ispunct), text.end());
    
    // 分割单词
    stringstream ss(text);
    string word;
    map<string, int> wordCount;
    
    while (ss >> word) {
        wordCount[word]++;
    }
    
    // 找出最常出现的单词
    string commonWord;
    int maxCount = 0;
    
    for (const auto& pair : wordCount) {
        if (pair.second > maxCount) {
            maxCount = pair.second;
            commonWord = pair.first;
        }
    }
    
    cout << "最常出现的单词: '" << commonWord 
         << "' 出现次数: " << maxCount << endl;
    
    return 0;
}

章节 1. 字符型

开放

题目 尝试 AC 难度
P894   【入门】输出ascii码对应的字符 6 3 10
P896   【入门】判断是什么字符 6 2 10
P158   【入门】大小写转换 11 2 10
P895   【入门】求下一个字母 0 0 (无)
P900   【入门】字母矩形1 0 0 (无)
P901   【入门】字母矩形2 0 0 (无)
P902   【入门】字母直角1 0 0 (无)
P903   【入门】字母直角2 0 0 (无)
1179   【入门】字符图形10-字母三角 0 0 (无)
P68   【入门】字符图形11-字母正三角 0 0 (无)
P784   【入门】数组查找及替换 0 0 (无)
P898   【入门】素数字母 0 0 (无)
P899   【入门】回文字母 0 0 (无)

章节 2. 字符串基础

开放

题目 尝试 AC 难度
639   【入门】时间的差! 2 2 10
527   【入门】数字和 4 2 10
564   【基础】国王的魔镜 2 2 10
839   【入门】简单加密 4 2 10
942   【基础】找字典码最小的字符串 2 2 10
937   【入门】字符串对比 4 2 10
940   【入门】出现次数最多的小写字母 5 2 10
769   【入门】判断是否构成回文 2 2 10
640   【入门】字符串中的空格移位 2 2 10
557   【基础】删除字符串中间的* 7 2 10
563   【入门】字符串的反码 5 2 10
755   【入门】看完动漫要几天? 2 2 10
765   【基础】时钟旋转(2) 11 2 10
855   【入门】字符串加密 4 2 10

章节 3. 字符串进阶

开放

题目 尝试 AC 难度
879   【基础】我是第几个单词 5 2 10
538   【入门】调换位置 2 2 10
560   【入门】简单a*b 2 2 10
634   【入门】简单a+b 3 2 10
1357   【入门】词组缩写 12 2 10
1468   【基础】字符串压缩 3 2 10
1479   【基础】字符串解压 24 2 9
1490   【基础】字符串连接 4 2 10
1501   【入门】统计单词个数 4 2 10
1512   【基础】求英文句子中的最长单词 1 1 10
641   【入门】正整数N转换成一个二进制数 2 1 10
642   【入门】查找子串并替换 9 2 10
630   【基础】找最长单词 6 2 10
505   【基础】隐藏的最大整数 8 2 10
516   【基础】趣味填空 2 2 10
562   【入门】保留整数 4 1 10