Appearance
字符串
在C++中,字符串可以通过C风格字符数组或C++的string类来处理。本章将详细介绍C++字符串的定义、操作和常用函数。
C风格字符串
cpp
#include <iostream>
#include <cstring> // C字符串函数头文件
using namespace std;
int main() {
// ============ C风格字符串定义 ============
// 字符数组,以'\0'结尾
char str1[] = "Hello"; // 自动添加'\0',大小为6
// 等价于
char str2[] = {'H', 'e', 'l', 'l', 'o', '\0'};
// 指定大小
char str3[10] = "Hello"; // 剩余位置填充'\0'
// 指针指向字符串字面量(只读)
const char* str4 = "Hello"; // 不能修改
// ============ 输出C字符串 ============
cout << "str1: " << str1 << endl;
cout << "str4: " << str4 << endl;
// 逐个字符输出
cout << "逐个字符: ";
for (int i = 0; str1[i] != '\0'; i++) {
cout << str1[i];
}
cout << endl;
// ============ C字符串函数 ============
char source[] = "Hello, World!";
char dest[50];
// strlen:获取字符串长度(不包括'\0')
cout << "\nstrlen: " << strlen(source) << endl;
// strcpy:复制字符串
strcpy(dest, source);
cout << "strcpy: " << dest << endl;
// strncpy:安全复制(指定最大长度)
strncpy(dest, source, 5);
dest[5] = '\0'; // 手动添加结束符
cout << "strncpy: " << dest << endl;
// strcat:连接字符串
char greeting[50] = "Hello";
strcat(greeting, ", C++!");
cout << "strcat: " << greeting << endl;
// strncat:安全连接
char name[50] = "Hello";
strncat(name, " World!", 4); // 只连接前4个字符
cout << "strncat: " << name << endl;
// strcmp:比较字符串
char s1[] = "apple";
char s2[] = "banana";
cout << "\nstrcmp(s1, s2): " << strcmp(s1, s2) << endl; // 负数(s1 < s2)
cout << "strcmp(s2, s1): " << strcmp(s2, s1) << endl; // 正数(s2 > s1)
cout << "strcmp(s1, s1): " << strcmp(s1, s1) << endl; // 0(相等)
// strchr:查找字符
char* pos = strchr(source, 'W');
if (pos != nullptr) {
cout << "\n找到'W'在位置: " << (pos - source) << endl;
}
// strstr:查找子字符串
char* sub = strstr(source, "World");
if (sub != nullptr) {
cout << "找到\"World\"在位置: " << (sub - source) << endl;
}
return 0;
}C++ string类
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
// ============ string定义和初始化 ============
// 默认构造
string s1; // 空字符串
// 从C字符串构造
string s2("Hello");
// 从另一个string构造
string s3(s2);
// 从重复字符构造
string s4(5, 'a'); // "aaaaa"
// 从子串构造
string s5("Hello World", 5); // "Hello"
// 从string的子串构造
string s6(s2, 2, 3); // 从位置2开始取3个字符 -> "llo"
// 使用=赋值
string s7 = "Hello";
// 使用列表初始化
string s8 = {'H', 'e', 'l', 'l', 'o'};
cout << "s1: \"" << s1 << "\"" << endl;
cout << "s2: " << s2 << endl;
cout << "s4: " << s4 << endl;
cout << "s5: " << s5 << endl;
cout << "s6: " << s6 << endl;
// ============ string基本操作 ============
string str = "Hello";
// 获取长度
cout << "\n长度: " << str.length() << endl;
cout << "大小: " << str.size() << endl; // 等价于length()
cout << "是否为空: " << (str.empty() ? "是" : "否") << endl;
// 访问字符
cout << "str[0]: " << str[0] << endl; // H(不检查边界)
cout << "str.at(1): " << str.at(1) << endl; // e(检查边界)
cout << "str.front(): " << str.front() << endl; // H
cout << "str.back(): " << str.back() << endl; // o
// 修改字符
str[0] = 'h';
cout << "修改后: " << str << endl;
// C字符串转换
const char* cstr = str.c_str(); // 返回C风格字符串
cout << "C字符串: " << cstr << endl;
// ============ string连接 ============
string s = "Hello";
// 使用+=
s += " ";
s += "World";
cout << "\n连接后: " << s << endl;
// 使用append
s.append("!");
cout << "append后: " << s << endl;
// 使用+
string result = s + " Welcome";
cout << "+连接: " << result << endl;
// push_back添加字符
s.push_back('!');
cout << "push_back后: " << s << endl;
// ============ string插入和删除 ============
string text = "Hello World";
// insert:在指定位置插入
text.insert(5, " C++"); // 在位置5插入
cout << "\ninsert后: " << text << endl;
// erase:删除字符
text.erase(5, 4); // 从位置5开始删除4个字符
cout << "erase后: " << text << endl;
// clear:清空
string temp = "temp";
temp.clear();
cout << "clear后长度: " << temp.length() << endl;
// pop_back:删除最后一个字符
text.pop_back();
cout << "pop_back后: " << text << endl;
// ============ string子串 ============
string original = "Hello, World!";
// substr:获取子串
string sub1 = original.substr(7); // 从位置7到末尾 -> "World!"
string sub2 = original.substr(0, 5); // 从位置0开始取5个 -> "Hello"
cout << "\nsubstr(7): " << sub1 << endl;
cout << "substr(0, 5): " << sub2 << endl;
return 0;
}string查找和替换
cpp
#include <iostream>
#include <string>
using namespace std;
int main() {
// ============ 查找 ============
string text = "Hello, World! Hello, C++!";
// find:查找子串,返回位置(未找到返回string::npos)
size_t pos = text.find("World");
if (pos != string::npos) {
cout << "找到\"World\"在位置: " << pos << endl;
}
// 从指定位置开始查找
pos = text.find("Hello", 5); // 从位置5开始
if (pos != string::npos) {
cout << "第二个\"Hello\"在位置: " << pos << endl;
}
// rfind:从后向前查找
pos = text.rfind("Hello");
cout << "rfind \"Hello\"位置: " << pos << endl;
// find_first_of:查找第一个匹配字符集中的任一字符
pos = text.find_first_of("aeiou");
cout << "第一个元音字母位置: " << pos << endl;
// find_last_of:查找最后一个匹配字符集中的任一字符
pos = text.find_last_of("aeiou");
cout << "最后一个元音字母位置: " << pos << endl;
// find_first_not_of:查找第一个不匹配的字符
pos = text.find_first_not_of("Helo, !");
cout << "第一个不匹配的字符位置: " << pos << endl;
// ============ 替换 ============
string str = "Hello, World!";
// replace:替换指定范围的字符
str.replace(7, 5, "C++"); // 从位置7开始替换5个字符
cout << "\nreplace后: " << str << endl;
// 替换所有出现的子串
string message = "I like cats. Cats are cute. cats are friendly.";
string from = "cats";
string to = "dogs";
pos = 0;
while ((pos = message.find(from, pos)) != string::npos) {
message.replace(pos, from.length(), to);
pos += to.length();
}
cout << "替换后: " << message << endl;
// ============ 比较 ============
string a = "apple";
string b = "banana";
cout << "\n比较结果:" << endl;
cout << "a.compare(b): " << a.compare(b) << endl; // 负数(a < b)
cout << "b.compare(a): " << b.compare(a) << endl; // 正数(b > a)
cout << "a.compare(a): " << a.compare(a) << endl; // 0(相等)
// 比较运算符
cout << "a == b: " << (a == b) << endl;
cout << "a < b: " << (a < b) << endl;
cout << "a != b: " << (a != b) << endl;
return 0;
}字符串流
cpp
#include <iostream>
#include <string>
#include <sstream> // 字符串流头文件
using namespace std;
int main() {
// ============ stringstream ============
// 字符串到数字的转换
string numStr = "123 45.67";
istringstream iss(numStr);
int intVal;
double doubleVal;
iss >> intVal >> doubleVal;
cout << "字符串转数字:" << endl;
cout << "int: " << intVal << endl;
cout << "double: " << doubleVal << endl;
// 数字到字符串的转换
ostringstream oss;
oss << "整数: " << 123 << ", 浮点数: " << 45.67;
string result = oss.str();
cout << "\n数字转字符串:" << endl;
cout << result << endl;
// ============ C++11转换函数 ============
// 数字转字符串
string s1 = to_string(123);
string s2 = to_string(3.14);
string s3 = to_string(123.456789);
cout << "\nto_string:" << endl;
cout << "int: " << s1 << endl;
cout << "double: " << s2 << endl;
cout << "double: " << s3 << endl;
// 字符串转数字
int i = stoi("123");
long l = stol("1234567890");
double d = stod("3.14");
float f = stof("3.14");
cout << "\n字符串转数字:" << endl;
cout << "stoi: " << i << endl;
cout << "stol: " << l << endl;
cout << "stod: " << d << endl;
cout << "stof: " << f << endl;
// 处理不同进制的字符串
int binary = stoi("1010", nullptr, 2); // 二进制
int octal = stoi("12", nullptr, 8); // 八进制
int hex = stoi("FF", nullptr, 16); // 十六进制
cout << "\n不同进制:" << endl;
cout << "二进制1010: " << binary << endl;
cout << "八进制12: " << octal << endl;
cout << "十六进制FF: " << hex << endl;
// ============ 分割字符串 ============
string sentence = "Hello World C++ Programming";
istringstream iss2(sentence);
string word;
cout << "\n分割字符串:" << endl;
while (iss2 >> word) {
cout << word << endl;
}
// 使用自定义分隔符
string data = "apple,banana,orange,grape";
istringstream iss3(data);
string item;
cout << "\n逗号分隔:" << endl;
while (getline(iss3, item, ',')) {
cout << item << endl;
}
return 0;
}字符串应用
cpp
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
using namespace std;
// ============ 字符串处理函数 ============
// 去除首尾空白
string trim(string str) {
// 去除前导空白
size_t start = str.find_first_not_of(" \t\n\r");
if (start == string::npos) return "";
// 去除尾部空白
size_t end = str.find_last_not_of(" \t\n\r");
return str.substr(start, end - start + 1);
}
// 分割字符串
vector<string> split(const string& str, char delimiter) {
vector<string> tokens;
stringstream ss(str);
string token;
while (getline(ss, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}
// 连接字符串
string join(const vector<string>& vec, const string& delimiter) {
string result;
for (size_t i = 0; i < vec.size(); i++) {
if (i > 0) result += delimiter;
result += vec[i];
}
return result;
}
int main() {
// ============ 大小写转换 ============
string text = "Hello World";
// 转大写
string upper = text;
transform(upper.begin(), upper.end(), upper.begin(), ::toupper);
cout << "大写: " << upper << endl;
// 转小写
string lower = text;
transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
cout << "小写: " << lower << endl;
// 手动转换
string manual = text;
for (char& c : manual) {
if (islower(c)) c = toupper(c);
else if (isupper(c)) c = tolower(c);
}
cout << "大小写互换: " << manual << endl;
// ============ 字符串反转 ============
string original = "Hello";
string reversed = original;
reverse(reversed.begin(), reversed.end());
cout << "\n反转: " << original << " -> " << reversed << endl;
// ============ 判断回文 ============
auto isPalindrome = [](const string& s) {
string filtered;
for (char c : s) {
if (isalnum(c)) {
filtered += tolower(c);
}
}
int left = 0, right = filtered.length() - 1;
while (left < right) {
if (filtered[left] != filtered[right]) {
return false;
}
left++;
right--;
}
return true;
};
cout << "\n回文判断:" << endl;
cout << "A man a plan a canal Panama: " << (isPalindrome("A man a plan a canal Panama") ? "是" : "否") << endl;
cout << "racecar: " << (isPalindrome("racecar") ? "是" : "否") << endl;
cout << "hello: " << (isPalindrome("hello") ? "是" : "否") << endl;
// ============ 字符串统计 ============
string sentence = "Hello World! 123";
int letters = 0, digits = 0, spaces = 0, others = 0;
for (char c : sentence) {
if (isalpha(c)) letters++;
else if (isdigit(c)) digits++;
else if (isspace(c)) spaces++;
else others++;
}
cout << "\n字符串统计:" << endl;
cout << "字母: " << letters << endl;
cout << "数字: " << digits << endl;
cout << "空格: " << spaces << endl;
cout << "其他: " << others << endl;
// ============ 使用自定义函数 ============
string padded = " Hello World ";
cout << "\n去除空白: \"" << trim(padded) << "\"" << endl;
vector<string> parts = split("apple,banana,orange", ',');
cout << "\n分割结果:" << endl;
for (const string& part : parts) {
cout << "- " << part << endl;
}
vector<string> words = {"Hello", "World", "C++"};
cout << "\n连接结果: " << join(words, " ") << endl;
return 0;
}本章小结
本章学习了:
- C风格字符串:字符数组、strlen、strcpy、strcmp等函数
- string类:定义、初始化、基本操作
- string操作:连接、插入、删除、子串
- string查找:find、rfind、find_first_of等
- 字符串转换:to_string、stoi、stod、stringstream
- 字符串应用:大小写转换、反转、回文判断
下一章,我们将学习面向对象基础,了解C++类与对象的概念。
