将char *转换为std :: string


262

我需要使用std::string来存储由检索的数据fgets()。为此,我需要将char*返回值从fgets()转换为std::string并存储在数组中。如何才能做到这一点?

Answers:


376

std::string 为此有一个构造函数:

const char *s = "Hello, World!";
std::string str(s);

请注意,此构造会深度复制字符列表,s并且s不应将其复制为nullptr,否则行为未定义。


6
如果会发生什么呢?
卡森·迈尔斯

14
Standard表示构造函数参数“不得为null指针”-它未指定引发任何异常。

24
是浅拷贝还是深拷贝?

4
@pushkin No str只是一个变量名。它可以是任何东西:SabclIstrHelloWorld。显然,有些选择比其他选择更好。但是对于这个例子str是完全可以接受的。
幻灭了

10
@Madhatter这是一个深复制。指针分配将保留,字符串将使自己成为新分配。
moodboom

127

如果您已经知道char *的大小,请改用它

char* data = ...;
int size = ...;
std::string myString(data, size);

这不使用strlen。

编辑:如果字符串变量已经存在,请使用assign():

std::string myString;
char* data = ...;
int size = ...;
myString.assign(data, size);

1
有点疑问,尤金。如果直到例程的稍后才填充数据,那么如何初始化myString?您只是在填充myString变量时声明了吗?
IcedD​​ante

2
int大小= strlen(数据);
弗拉德

@vlad:这个想法是,您知道来自其他来源和/或数据的大小不是C字符串(具有嵌入的null或不以null结尾)。如果您有C字符串,则只需执行myString = data;它会为您运行strlen或等效功能。
尤金2015年

1
@huseyintugrulbuyukisik您仍然需要正确处理原始内存-std :: string将复制字节,并且不拥有所有权。
尤金(Eugene)

2
@ZackLee它将为这些字节分配新的内存,并将它们全部复制到那里,直到达到为止。如果希望进行浅拷贝,则需要将一个std :: string复制到另一个。然后,我认为某些实现可以做一个浅表复制。
尤金(Eugene)

30

大多数答案都谈论建造 std::string

如果已经构建,则只需使用赋值运算符

std::string oString;
char* pStr;

... // Here allocate and get character string (e.g. using fgets as you mentioned)

oString = pStr; // This is it! It copies contents from pStr to oString

28

我需要使用std :: string来存储fgets()检索到的数据。

为什么fgets()在编程C ++时使用?为什么不std::getline()呢?


18

通过构造函数传递它:

const char* dat = "my string!";
std::string my_string( dat );

您可以使用函数string.c_str()进行其他选择:

std::string my_string("testing!");
const char* dat = my_string.c_str();

3
c_str()返回const char*
Steve Jessop

1
正确,您不能(不应)通过c_str()修改std :: string中的数据。如果您打算更改数据,然后从c_str(在C字符串)应memcpy'd
卡森·迈尔斯

11
const char* charPointer = "Hello, World!\n";
std::string strFromChar;
strFromChar.append(charPointer);
std::cout<<strFromChar<<std::endl;

6
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;

5

我想提到一种使用用户定义文字的新方法s。这不是什么新鲜事物,但是会更加普遍,因为它是在C ++ 14标准库中添加的。

在一般情况下是多余的:

string mystring = "your string here"s;

但是它允许您对宽字符串也使用自动:

auto mystring = U"your UTF-32 string here"s;

这才是真正闪耀的地方:

string suffix;
cin >> suffix;
string mystring = "mystring"s + suffix;

2

我一直在努力与MSVC2005一起使用std::string(char*)构造函数,就像最受好评的答案一样。正如我在始终受信任的http://en.cppreference.com/w/cpp/string/basic_string/basic_string上将此变体列出为#4一样,我认为即使是旧的编译器也可以提供此变体。

我花了很长时间才意识到这个构造函数绝对拒绝与之匹配(unsigned char*)!我收到了关于无法与std::string参数类型匹配的这些无法理解的错误消息,这绝对不是我想要的。只是用争论std::string((char*)ucharPtr)解决了我的问题......!


0
char* data;
std::string myString(data);

9
这将导致不确定的行为。

1
仅使用这两行,data仍未初始化(空)。
heltonbiker 2011年

1
如果没有提供指针的真正“长度”,此代码可能会导致数据丢失,您的std :: string会比原始char *“更短” *
Andiana

0

不知道为什么除了Erik之外没有人提到这一点,但是根据此页面,赋值运算符可以正常工作。无需使用构造函数,.assign()或.append()。

std::string mystring;
mystring = "This is a test!";   // Assign C string to std:string directly
std::cout << mystring << '\n';

1
它似乎确实可以正常工作,但是当我这样做时,我开始在程序结束时遇到Valgrind报告可访问块的问题,这源于=(和+=)内部的“新” 。似乎不是像这样的文字发生,而是像char*事情一样。本文讨论了此类报告是否实际上是泄漏的问题。但是,如果我将分配更改destString = std::string(srcCharPtr);为valgrind,泄漏报告将消失。YMMV。
HostileFork说不要信任2014年

HostileFork的评论可能会让您相信,从char *构造字符串(例如从fgets构造)将使std :: string管理此内存的寿命。然而,这种情况并非如此。参见标准21.4.2.7和.9 Constructs an object of class basic_string and determines its initial string value from the array。它说的是价值,与缓冲区或指针所有权无关。
Erik van Velzen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.