将char*转换为std::string

363

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

13个回答

510

std::string有一个针对此目的的构造函数:

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

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


7
如果是这样,会发生什么? - Carson Myers
16
标准规定构造函数参数 "不得为 null 指针" - 但它没有指定任何异常被抛出。 - anon
29
这是浅拷贝还是深拷贝? - user1197918
5
@pushkin,“str”只是一个变量名,它可以是任何东西:“S”,“abc”,“I”,“strHelloWorld”。显然,有些选项比其他选项更好。但对于这个例子来说,“str”是相当可接受的。 - Disillusioned
13
@Madhatter 这是深拷贝。指针分配将保持不变,字符串会进行新的分配。 - moodboom
显示剩余10条评论

173

如果您已经知道 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被填充时声明该变量吗? - IcedDante
3
变量size的值等于字符串data的长度。 - Vlad
@vlad:这个想法是你从其他来源知道大小和/或数据不是C字符串(具有嵌入的null或不以null结尾)。如果你有一个C字符串,你可以简单地做myString = data;它会为你运行strlen或等效的操作。 - Eugene
1
@huseyintugrulbuyukisik,您仍需要适当释放原始内存-- std :: string将复制字节,而不是拥有所有权。 - Eugene
2
@ZackLee 它将为这些字节分配新的内存并将它们全部复制到那里,因此它会尽可能深入。如果您想要浅拷贝的潜力,您需要将一个std::string复制到另一个std::string中。然后一些实现可能会进行浅拷贝。 - Eugene
显示剩余3条评论

60

大部分答案都是关于构造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

2
pStr 在分配给 oString 后是否可以被删除而不影响后者? - Sisir
是的 @Atul,我有同样的问题,我们可以在使用赋值运算符给 char* 赋值后安全地删除它吗?赋值运算符会进行深拷贝吗? - undefined
@ZoomIn std::string的operator=实际上并没有进行深拷贝,而是浅拷贝。它将char*转换为std::string,正如OP所要求的那样。 - undefined
@Atul,那是不是意味着我们在赋值后不能删除pStr? - undefined
1
@ZoomIn 没错,我们在赋值后不能删除pStr。 - undefined

32
我需要使用std :: string来存储通过fgets()检索的数据。 为什么在编程C ++时要使用fgets()? 为什么不使用std :: getline()?

21

通过构造函数传递它:

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();

5
c_str() 返回 const char* - Steve Jessop
1
对于std::string类型的数据,你不能(也不应该)通过c_str()来修改它。如果你想要改变数据,那么应该使用memcpy函数将c_str()返回的C字符串复制一份。 - Carson Myers

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

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

7

将C语言风格的字符串转换为C++ std字符串更容易

我们可以用三种方法将C语言风格的字符串转换为C++ std字符串

第一种方法是使用构造函数,

char chText[20] = "I am a Programmer";
// using constructor
string text(chText);

第二种方法是使用string::assign方法

// char string
char chText[20] = "I am a Programmer";

// c++ string
string text;

// convertion from char string to c++ string
// using assign function
text.assign(chText);

第三个是赋值运算符(=),在这种情况下,字符串类使用运算符重载

// char string
char chText[20] = "I am a Programmer";

// c++ string
// convertion from char string to c++ string using assignment operator overloading
string text = chText;

第三种写法可以如下:

// char string
char chText[20] = "I am a Programmer";

// c++ string
string text;


// convertion from char string to c++ string
text = chText;

第三种方法比较简单,并且可以在两种情况下使用:

  1. 我们声明和初始化时
  2. 我们在对象创建或初始化后多次赋值时

7

我想提到一种新方法,它使用了用户自定义字面量s。这并不是新的东西,但是由于它被添加到了C++14标准库中,因此它将变得更加常见。

在一般情况下,这大多是多余的:

string mystring = "your string here"s;

但它允许你使用auto,同时支持宽字符串:

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

这正是它的亮点所在:

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

2
这很好,但是你的代码似乎需要加上using namespace std::literals;才能使用这个。 - undefined

6

我刚刚在使用MSVC2005时遇到了问题,想要像最受欢迎的答案一样使用std::string(char*)构造函数。我看到这种变体在始终可信赖的http://en.cppreference.com/w/cpp/string/basic_string/basic_string上排名第四,所以即使是旧编译器也提供了这种构造函数。

我花了很长时间才意识到,这个构造函数绝对不会匹配(unsigned char*)作为参数!我得到了这些难以理解的错误消息,说明无法与std::string参数类型匹配,这绝对不是我想要的结果。只需使用std::string((char*)ucharPtr)将参数强制转换即可解决我的问题...真是太傻了!


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