C++怎么定义字符串_C++中string类的基本用法【入门】

2次阅读

必须包含#include <String>才能使用std::string,它不属于<iostream>且位于std命名空间;常见错误是未引入头文件导致“string未声明”;正确用法包括std::string、using std::string或using Namespace std(不推荐)。

C++怎么定义字符串_C++中string类的基本用法【入门】

string 不是关键字,得 #include <string> 才能用

很多人写完 std::string s = "hello"; 就报错,编译器说 string 未声明——不是你拼错了,是根本没引入头文件。c++ 标准库的 string 类不在 <iostream> 里,也不在全局命名空间,它藏在 <string> 头文件中,且属于 std 命名空间。

常见错误现象:Error: 'string' was not declared in this scope

  • 必须加 #include <string>,缺一不可
  • 要么写全 std::string,要么加 using std::string;(不建议 using namespace std;
  • 别和 C 风格字符串char[]const char*)混淆:它们类型不同,不能直接赋值给未初始化的 std::string 变量(但可以隐式构造)

初始化 string 的 4 种常见写法,别乱混用

初始化方式影响底层行为,尤其在性能敏感或移动语义启用时。比如空字符串、从 C 字符串构造、拷贝、移动,背后调用的构造函数完全不同。

使用场景:读配置、拼接日志、接收函数返回值

立即学习C++免费学习笔记(深入)”;

  • std::string s; —— 默认构造,内部指针为空或指向小缓冲区(SSO),不分配内存
  • std::string s = "abc"; —— 字符串字面量构造,隐式调用 string(const char*)
  • std::string s(other_string); —— 拷贝构造;如果 other_string 是右值(如函数返回值),C++11 起会自动触发移动构造,避免深拷贝
  • std::string s(std::move(temp)); —— 显式移动,适用于临时对象已无用时,把内部缓冲区“转手”给新对象

容易踩的坑:std::string s = std::string("hello"); 看似无害,但可能多一次不必要的临时对象构造(编译器通常会优化掉,但别依赖)

用 c_str() 和 data() 时,注意生命周期和空字符

当你需要把 std::string 传给 C API(比如 fopenprintf、OpenGL 函数),必须转成 const char*。这时选 c_str() 还是 data()?差别很实际。

  • s.c_str() 保证以 '' 结尾,返回值可安全用于任何要求 NULL-terminated 的 C 函数
  • s.data() 在 C++11 中不保证结尾有 ''(C++17 起才保证),只适合传给明确接受长度参数的函数(如 write(2)std::string_view 构造)
  • 二者返回指针都只在 s 生命周期内有效;一旦 s 被修改、销毁或重新分配,指针立刻失效

典型错误:const char* p = s.c_str(); s.clear(); printf("%s", p); → 未定义行为,很可能打印乱码或崩溃

== 比较安全,但 find / substr 等操作要防越界

std::string 的比较操作符(==< 等)语义清晰,基本不会出错。真正容易翻车的是下标访问、查找、子串提取这些带索引的操作。

  • s[i] 不检查越界(i ≥ s.length() 时是未定义行为),调试模式下某些 STL 实现会 abort,但发布版直接崩
  • s.at(i) 会抛 std::out_of_range 异常,适合需要显式错误处理的场景
  • s.find("x") 找不到时返回 std::string::npos(一个极大值,通常是 size_t(-1)),别直接当整数用:if (s.find("x") < 5) 在没找到时会恒成立
  • s.substr(pos, len) 中,如果 pos > s.Length(),直接抛异常;len 超出剩余长度则自动截断——这点反而比 C 安全

性能提示:find 是 O(N×M) 的朴素匹配,别在大文本里反复调用它做模糊搜索;真要高效查,考虑 std::string_view + KMP,或换用 std::Regex(代价更高)

string 的坑不在语法多难,而在“看起来像内置类型,实则行为受标准版本、编译器实现、甚至优化等级影响”。比如 SSO(短字符串优化)是否开启、移动构造是否真的发生、data() 是否带 ‘’,这些细节在跨平台或升级编译器后可能突然暴露。

text=ZqhQzanResources