跳到主要内容

变量 » 字符串 » 常见问题

忘记包含头文件

❌ 错误代码
int main()
{
std::string s = "Hello";
}

可能的错误消息

In function 'int main()':
error: 'string' is not a member of 'std'
2 | std::string s = "Hello";
| ^~~~~~
note: 'std::string' is defined in header '<string>'; did you forget to '#include <string>'?
+++ |+#include <string>
1 | int main() {

解决方案

在文件顶部添加 #include <string>

将数字视为字符串

❌ 错误代码
#include <string>

int main()
{
std::string s = 123;
}

可能的错误消息:

In function 'int main()':
error: conversion from 'int' to non-scalar type 'std::string' {aka 'std::__cxx11::basic_string<char>'} requested
4 | std::string s = 123;
| ^~~

解决方案

使用 std::to_string 将整数转换为字符串。有关更多信息,请参阅数字和字符串之间的转换以及数字和字符串

将字符串视为数字

❌ 错误代码
#include <string>

int main()
{
std::string s = "123";
s *= 15;
}

可能的错误消息:

In function 'int main()':
error: no match for 'operator*=' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
5 | s *= 15;
| ~~^~~~~

解决方案

使用 std::stoistd::stof 将字符串转换为代数数值。有关更多信息,请参阅数字和字符串之间的转换以及数字和字符串

连接两个字符串字面量

❌ 错误代码
#include <string>

int main()
{
std::string s = "Hello " + "World";
}

可能的错误消息:

In function 'int main()':
error: invalid operands of types 'const char [7]' and 'const char [6]' to binary 'operator+'
5 | std::string s = "Hello " + "World";
| ~~~~~~~~ ^ ~~~~~~~
| | |
| | const char [6]
| const char [7]

解决方案

无论何时你在 C++ 文件中看到 "TEXT",这都被称为一个 字符串字面量。基本上,这是一个花哨的术语,表示这是一个硬编码的文本值。然而,关键的是,字符串字面量的类型不是 std::string。相反,它是 const char[N],其中 N 是文本长度 + 1。上面的 GCC 错误最好地说明了这一点。

const char[N] 称为一个 数组。我们将在后面的章节中介绍数组,但这里重要的知识是,你不能将两个数组相加,因为它们不是数字。std::string 为我们提供了通过 + 连接字符串的能力。

最简单的解决方法是直接像 "Hello World" 那样组合字符串字面量。

使用 std::getline 跳过输入

⚠️ 有问题的代码
#include <string>

int main()
{
int age;
std::string full_name;

std::cout << "Enter your age: ";
std::cin >> age;

std::cout << "Enter your full name: ";
std::getline(std::cin, full_name); // This line is seemingly skipped

std::cout << "\nYour name is " << full_name << " and your age is " << age;
}

意外行为

你可能会发现,在使用 std::cin >> ... 之后使用 std::getline 时,它似乎跳过了 std::getline。在上面的例子中,它会询问你的年龄,你会输入比如 23,然后它会询问你的全名,但不会让你输入名字。相反,它会立即输出 你的名字是,你的年龄是 23

解决方案

理解为什么会这样有点棘手。需要记住的关键是,当你使用 std::cin >> ... 时,它会从 stdin 读取输入,直到它看到空白字符(空格、换行符或制表符)。当你按下键盘上的 Enter 来输入年龄时,它会将一个 换行符 \n 放入 stdin。然后 std::cin 读取你输入的数字,并在该换行符处停止,但不移除 \n 字符

std::getline 使用这些 \n 字符的存在来确定一整行的结束位置。因此,当它尝试从 stdin (std::cin) 读取一行直到下一个 \n 时,它会立即看到由之前的 std::cin >> age; 留下的 \n 字符。因此,它将其解释为空行,并将 full_name 设置为空字符串 ""

解决这个问题的方法是另一个 方法 叫做 ignore。这个方法会告诉 std::cin 跳过上一个操作留下的剩余换行符。无论何时你计划在 std::cin >> ... 操作之后使用 std::getline,你都应该在它们之间放置方法调用 std::cin.ignore();,就像下面的简化示例一样

如何使用 ignore 方法
int age;
std::string full_name;

std::cin >> age;

std::cin.ignore();

std::getline(std::cin, full_name);

变量 » 字符串 » 常见问题

忘记包含头文件

❌ 错误代码
int main()
{
std::string s = "Hello";
}

可能的错误消息

In function 'int main()':
error: 'string' is not a member of 'std'
2 | std::string s = "Hello";
| ^~~~~~
note: 'std::string' is defined in header '<string>'; did you forget to '#include <string>'?
+++ |+#include <string>
1 | int main() {

解决方案

在文件顶部添加 #include <string>

将数字视为字符串

❌ 错误代码
#include <string>

int main()
{
std::string s = 123;
}

可能的错误消息:

In function 'int main()':
error: conversion from 'int' to non-scalar type 'std::string' {aka 'std::__cxx11::basic_string<char>'} requested
4 | std::string s = 123;
| ^~~

解决方案

使用 std::to_string 将整数转换为字符串。有关更多信息,请参阅数字和字符串之间的转换以及数字和字符串

将字符串视为数字

❌ 错误代码
#include <string>

int main()
{
std::string s = "123";
s *= 15;
}

可能的错误消息:

In function 'int main()':
error: no match for 'operator*=' (operand types are 'std::string' {aka 'std::__cxx11::basic_string<char>'} and 'int')
5 | s *= 15;
| ~~^~~~~

解决方案

使用 std::stoistd::stof 将字符串转换为代数数值。有关更多信息,请参阅数字和字符串之间的转换以及数字和字符串

连接两个字符串字面量

❌ 错误代码
#include <string>

int main()
{
std::string s = "Hello " + "World";
}

可能的错误消息:

In function 'int main()':
error: invalid operands of types 'const char [7]' and 'const char [6]' to binary 'operator+'
5 | std::string s = "Hello " + "World";
| ~~~~~~~~ ^ ~~~~~~~
| | |
| | const char [6]
| const char [7]

解决方案

无论何时你在 C++ 文件中看到 "TEXT",这都被称为一个 字符串字面量。基本上,这是一个花哨的术语,表示这是一个硬编码的文本值。然而,关键的是,字符串字面量的类型不是 std::string。相反,它是 const char[N],其中 N 是文本长度 + 1。上面的 GCC 错误最好地说明了这一点。

const char[N] 称为一个 数组。我们将在后面的章节中介绍数组,但这里重要的知识是,你不能将两个数组相加,因为它们不是数字。std::string 为我们提供了通过 + 连接字符串的能力。

最简单的解决方法是直接像 "Hello World" 那样组合字符串字面量。

使用 std::getline 跳过输入

⚠️ 有问题的代码
#include <string>

int main()
{
int age;
std::string full_name;

std::cout << "Enter your age: ";
std::cin >> age;

std::cout << "Enter your full name: ";
std::getline(std::cin, full_name); // This line is seemingly skipped

std::cout << "\nYour name is " << full_name << " and your age is " << age;
}

意外行为

你可能会发现,在使用 std::cin >> ... 之后使用 std::getline 时,它似乎跳过了 std::getline。在上面的例子中,它会询问你的年龄,你会输入比如 23,然后它会询问你的全名,但不会让你输入名字。相反,它会立即输出 你的名字是,你的年龄是 23

解决方案

理解为什么会这样有点棘手。需要记住的关键是,当你使用 std::cin >> ... 时,它会从 stdin 读取输入,直到它看到空白字符(空格、换行符或制表符)。当你按下键盘上的 Enter 来输入年龄时,它会将一个 换行符 \n 放入 stdin。然后 std::cin 读取你输入的数字,并在该换行符处停止,但不移除 \n 字符

std::getline 使用这些 \n 字符的存在来确定一整行的结束位置。因此,当它尝试从 stdin (std::cin) 读取一行直到下一个 \n 时,它会立即看到由之前的 std::cin >> age; 留下的 \n 字符。因此,它将其解释为空行,并将 full_name 设置为空字符串 ""

解决这个问题的方法是另一个 方法 叫做 ignore。这个方法会告诉 std::cin 跳过上一个操作留下的剩余换行符。无论何时你计划在 std::cin >> ... 操作之后使用 std::getline,你都应该在它们之间放置方法调用 std::cin.ignore();,就像下面的简化示例一样

如何使用 ignore 方法
int age;
std::string full_name;

std::cin >> age;

std::cin.ignore();

std::getline(std::cin, full_name);