c_str()函数的作用是什么?

95

我理解c_str函数能够将一个可能为空结尾的字符串转换为以空字符结尾的字符串。

这是正确的吗?你可以举一些例子吗?

8个回答

107

c_str 返回一个指向以 null 结尾的字符串(即 C 风格字符串)的 const char*。当你想要将 std::string 的 "内容"¹ 传递给一个期望使用 C 风格字符串的函数时,这是非常有用的。

例如,考虑以下代码:

std::string string("Hello, World!");
std::size_t pos1 = string.find_first_of('w');

std::size_t pos2 = static_cast<std::size_t>(std::strchr(string.c_str(), 'w') - string.c_str());

if (pos1 == pos2) {
    std::printf("Both ways give the same result.\n");
}

点击此处查看示例

注:

¹ 这并非完全正确,因为 std::string(与 C 字符串不同)可以包含 \0 字符。如果包含,则接收 c_str() 返回值的代码会被欺骗,认为字符串比实际要短,因为它会将 \0 解释为字符串的结尾。


1
你在注释中提出的观点非常有趣:如果 std::string 已经包含 \0,那么 c_str 是否也会在字符串末尾追加 \0? - Amit Singh Tomar
3
是的,所以你将会有两个空字节 -- 一个是字符串中合法的部分,另一个是应该作为空终止符的。但是接收指针的C风格函数并不知道这一点。 - Jon
注意:许多C-API将要求两个参数(char const*,size_t),第二个参数是大小。 - Matthieu M.
这段代码有问题:string str("0.85"); newVolume = _tstof((TCHAR*)str.c_str()); 我该如何将 TCHAR* argv[] 输入的 0.85 转换成那种格式? - user285594
1
@YumYumYum,你不能将std::string与TCHAR混用,因为TCHAR的整个意义在于自动在char/wchar之间切换,而std::string仅以char为单位。你必须使用适当的抽象,或者干脆不使用TCHAR,始终进行Unicode构建。 - Jon
显示剩余3条评论

71

在C++中,你将字符串定义为

std::string MyString;

而不是

char MyString[20];

在编写C++代码时,你会遇到一些需要C字符串作为参数的C函数。
像下面这样:

void IAmACFunction(int abc, float bcd, const char * cstring);

现在有一个问题。你正在使用C++并且正在使用std::string字符串变量,但是这个C函数要求一个C字符串。如何将你的std::string转换为标准的C字符串?

像这样:

std::string MyString;
// ...
MyString = "Hello world!";
// ...
IAmACFunction(5, 2.45f, MyString.c_str());

这就是c_str()的作用。

请注意,对于std::wstring字符串,c_str()返回一个const w_char *


9
大多数涉及字符串的旧版C++和C函数使用const char*。通过STLstd::string,引入了string.c_str(),可以将std::string转换为const char*。这意味着,如果您承诺不更改缓冲区,您将能够使用只读字符串内容。 承诺=const char*。

1
@stl::string这个东西根本不存在。事实上,除了在某个博物馆里,根本就没有“STL”这样的东西存在。 - Kerrek SB
1
@Kerrek SB:STL(标准模板库)曾经被用作C++标准库的同义词。 - Peter Mortensen
这是来自2020年的一个例子。或者可能是由于旧书的原因。 - Peter Mortensen
这是2020年的一个例子。或者可能是因为旧书的原因。 - undefined
这是另一个例子(2010)-“我正在使用STL的string”。 - Peter Mortensen

8
在C/C++编程中,有两种类型的字符串:C字符串和标准字符串。使用<string>头文件,我们可以使用标准字符串。另一方面,C字符串只是普通字符数组。因此,为了将标准字符串转换为C字符串,我们使用c_str()函数。
例如:
// A string to a C-style string conversion //

const char *cstr1 = str1.c_str();
cout<<"Operation: *cstr1 = str1.c_str()"<<endl;
cout<<"The C-style string c_str1 is: "<<cstr1<<endl;
cout<<"\nOperation: strlen(cstr1)"<<endl;
cout<<"The length of C-style string str1 = "<<strlen(cstr1)<<endl;

输出结果将是:

Operation: *cstr1 = str1.c_str()
The C-style string c_str1 is: Testing the c_str

Operation: strlen(cstr1)
The length of C-style string str1 = 17

7

c_str()将C++字符串转换为C风格字符串,即以null结束的字节数组。当您希望将C++字符串传递给一个期望C风格字符串(例如Win32 API,POSIX风格函数等)的函数时,需要使用它。


5
我不会说“转换”,相反,这个函数“提供访问”一个适合的只读字符数组——很可能是在 std::string 的实现中一直存在的数组。 - Kerrek SB

6

这被用于使std::string与需要以空字符结尾的char*形式要求的C代码相互操作。


1
你将在两个程序之间传输字符串对象时使用它进行编码/解码。
假设你使用Base64在Python中对一些数组进行编码,然后想要在C++中将其解码。一旦你从Base64解码得到字符串,在C++中将其转换回浮点数数组,你所需要做的就是:
float arr[1024];
memcpy(arr, ur_string.c_str(), sizeof(float) * 1024);

这是相当常见的用法,我想。


1
那种代码不具备可移植性(包括字节序和浮点格式等)。 - Phil1970

0

const char* c_str() const;

该函数返回一个指向字符数组的指针,该数组包含表示字符串对象当前值的null-terminated sequence(即C字符串)。

该数组包含与字符串对象值相同的字符序列以及在末尾附加的另一个终止空字符('\0')。

std::string str = "hello";
std::cout << str;          // hello
printf("%s", str);         // ,²/☺
printf("%s", str.c_str()); // hello

为什么是 ²/☺?它从哪里来的? - Peter Mortensen
大部分或全部内容都是从其他地方复制的,例如这个tutorialspoint页面和其他地方(可能也被复制了)- tutorialspoint.com页面在第一句话中添加了“它”。主要来源可能是官方文档*std::string::data*,例如整个句子“该数组包括与字符串对象的值相同的字符序列以及在末尾附加的额外终止空字符('\0')。” - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接