关于 c_str()

关于c_str()的用法

引入

首先来看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <string.h>
std::string readFile(const char *path)
{
std::string str;
std::ifstream file;
std::stringstream stream;
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
file.open(path);
stream << file.rdbuf();
str = stream.str();
file.close();
}
catch (const std::exception &e)
{
std::cerr << e.what() << '\n';
}
return str;
}
int main()
{
freopen("output.txt", "w", stdout);
const char *c = readFile("a.txt").c_str();
printf("%s\n", c);
const char *d = readFile("b.txt").c_str();
printf("%s\n", c);
return 0;
}

a.txt:

a.txt
1
Every dog has it's day.

b.txt:

1
It never rains but it pours.

期待的结果自然是两遍 a.txt 中的内容,而当打开 output.txt 时,奇怪的事情发生了:

1
2
Every dog has it's day.
It never rains but it pours.

分析

c_str() 定义的注释中可以找到这样一句警告:

!!! warning
Do not modify or dire things may happen.

发生上面问题的原因在于 c_str() 返回的只是一个临时的指针,下一次操作正好用了相同的地址,使得内容发生了改变。

解决

将字符串复制出来即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
freopen("output.txt", "w", stdout);
std::string tmp;
tmp = readFile("a.txt");
char *c = new char[tmp.length()];
strcpy(c, tmp.c_str());
printf("%s\n", c);
tmp = readFile("b.txt");
char *d = new char[tmp.length()];
strcpy(d, tmp.c_str());
printf("%s\n", c);
return 0;
}

输出:

1
2
Every dog has it's day.
Every dog has it's day.

关于 c_str()
http://xiao-h.com/2021/07/20/about-c-str/
作者
小H
发布于
2021年7月20日
许可协议