I need to use an std::string
to store data retrieved by fgets()
. To do this I need to convert the char*
return value from fgets()
into an std::string
to store in an array. How can this be done?

- 11,357
- 8
- 43
- 88

- 6,114
- 7
- 29
- 26
13 Answers
std::string
has a constructor for this:
const char *s = "Hello, World!";
std::string str(s);
Note that this construct deep copies the character list at s
and s
should not be nullptr
, or else behavior is undefined.

- 354
- 6
- 13

- 33,081
- 21
- 109
- 146
-
7what will happen if it is? – Carson Myers Jul 28 '09 at 18:04
-
@Jesse What is your basis for saying such an exception is thrown? – Jul 28 '09 at 18:14
-
1@Neil, my implementation (gcc) does. I can't seem to find an official answer here. What is specified to happen? – Jesse Beder Jul 28 '09 at 18:16
-
Undefined behaviour, or so I have always believed. I'll look it up. – Jul 28 '09 at 18:17
-
16Standard says that the constructor parameter "shall not be a null pointer" - it doesn't specify that any exceptions are thrown. – Jul 28 '09 at 18:22
-
1Just to be picky, the behaviour (as pointed out by Neil) is "undefined" not "unspecified". There is a difference. The library doesn't say what happens if the pointer is null and so the behaviour is undefined. – Richard Corden Jul 29 '09 at 07:20
-
Hmmm... I always thought that since it wasn't in the specification, it was unspecified. But it appears (google indicates) that that's the definition of undefined. This strikes me as silly, but I changed it anyways. – Jesse Beder Jul 29 '09 at 16:59
-
2I believe the new standard throws an `std::logic_error` from within `basic_string` on null pointer. – Qix - MONICA WAS MISTREATED Jul 03 '14 at 04:49
-
29Is it shallow or deep copy ? – Jan 21 '15 at 01:36
-
@JesseBeder Should that be `string(s)` not `str(s)`? – pushkin Dec 28 '15 at 09:12
-
5@pushkin No `str` is just a variable name. It could be anything: `S`, `abc`, `l`, `I`, `strHelloWorld`. Obviously some choices are better than others. But for this example `str` is quite acceptable. – Disillusioned Mar 09 '16 at 23:21
-
1looks like this should be `std::string(s);` instead of `std::string str(s);` – nikk Jun 26 '16 at 22:51
-
13@Madhatter it is a deep copy. The pointer allocation will remain, and the string will make itself a new allocation. – moodboom Dec 01 '17 at 12:43
-
This answer is not accurate, it doesn't work for binary strings Eugene's answer is much generic and safer: https://stackoverflow.com/a/1195705/1481040 – Juanmi Taboada Sep 13 '18 at 16:47
If you already know size of the char*, use this instead
char* data = ...;
int size = ...;
std::string myString(data, size);
This doesn't use strlen.
EDIT: If string variable already exists, use assign():
std::string myString;
char* data = ...;
int size = ...;
myString.assign(data, size);

- 7,180
- 1
- 29
- 36
-
1Kind of a side question, Eugene. If **data** isn't populated until later in the routine, how do you initialize myString then? Do you simply declare the myString variable when it is populated? – IcedDante Aug 31 '11 at 16:29
-
3
-
@vlad: the idea is that you know the size from some other source and/or data is not a C-string (has embedded nulls or doesn't end in a null). If you have a C-string you can simply do myString = data; it will run strlen or equivalent for you. – Eugene Aug 04 '15 at 16:25
-
So we don't need to delete data? string takes care of that later? – huseyin tugrul buyukisik Jan 25 '18 at 01:34
-
1@huseyintugrulbuyukisik You still need to dispose of original memory properly -- std::string will copy bytes, it does not take ownership. – Eugene Jan 25 '18 at 16:39
-
@Eugene thank you for this. Now I'm 100% sure. I had a debug-dll release-exe problem which had problems with some allocate-in-dll, release-in-exe type functions. – huseyin tugrul buyukisik Jan 25 '18 at 17:18
-
-
2@ZackLee it will allocate new memory for the bytes and copy them all in there, so as deep as it gets. If you want potential for shallow copy, you need to copy one std::string into another. Then some implementations could do a shallow copy I think. – Eugene Aug 07 '18 at 17:25
Most answers talks about constructing std::string
.
If already constructed, just use assignment operator.
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

- 3,778
- 5
- 47
- 87
-
Can the `pStr` be deleted after it is assigned to `oString` without impacting the later? – Sisir Mar 15 '23 at 08:37
I need to use std::string to store data retrieved by fgets().
Why using fgets()
when you are programming C++? Why not std::getline()
?

- 13,042
- 3
- 41
- 59
Pass it in through the constructor:
const char* dat = "my string!";
std::string my_string( dat );
You can use the function string.c_str() to go the other way:
std::string my_string("testing!");
const char* dat = my_string.c_str();

- 36,288
- 32
- 162
- 271

- 46,512
- 18
- 65
- 82
-
5
-
1right, you can't (shouldn't) modify the data in a std::string via c_str(). If you intend to change the data, then the c string from c_str() should be memcpy'd – Carson Myers Jul 28 '09 at 18:06
const char* charPointer = "Hello, World!\n";
std::string strFromChar;
strFromChar.append(charPointer);
std::cout<<strFromChar<<std::endl;
char* data;
stringstream myStreamString;
myStreamString << data;
string myString = myStreamString.str();
cout << myString << endl;

- 1,809
- 4
- 31
- 46
Converting from C style string to C++ std string is easier
There is three ways we can convert from C style string to C++ std string
First one is using constructor,
char chText[20] = "I am a Programmer";
// using constructor
string text(chText);
Second one is using string::assign
method
// 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);
Third one is assignment operator(=), in which string class uses operator overloading
// 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;
third one can be also write like below -
// char string
char chText[20] = "I am a Programmer";
// c++ string
string text;
// convertion from char string to c++ string
text = chText;
Third one is little straight forward and can be used in both situation
- while we are declaring and initializing
- while we are assigning multiple times after object creation or initialization

- 2,558
- 2
- 25
- 44
I would like to mention a new method which uses the user defined literal s
. This isn't new, but it will be more common because it was added in the C++14 Standard Library.
Largely superfluous in the general case:
string mystring = "your string here"s;
But it allows you to use auto, also with wide strings:
auto mystring = U"your UTF-32 string here"s;
And here is where it really shines:
string suffix;
cin >> suffix;
string mystring = "mystring"s + suffix;

- 6,211
- 3
- 23
- 23
I've just been struggling with MSVC2005 to use the std::string(char*)
constructor just like the top-rated answer. As I see this variant listed as #4 on always-trusted http://en.cppreference.com/w/cpp/string/basic_string/basic_string , I figure even an old compiler offers this.
It has taken me so long to realize that this constructor absolute refuses to match with (unsigned char*)
as an argument ! I got these incomprehensible error messages about failure to match with std::string
argument type, which was definitely not what I was aiming for. Just casting the argument with std::string((char*)ucharPtr)
solved my problem... duh !

- 195
- 1
- 8
char* data;
std::string myString(data);

- 187,200
- 47
- 362
- 445
-
10
-
1
-
1Without true "length" of pointer provided, this code can cause lost data, your std::string will "more shorter" than the original char * – Andiana Nov 15 '16 at 01:48
-
`data` remain uninitialized maybe will causing `std::string` read garbage data – Blanket Fox Dec 26 '20 at 07:41
char* c1 = 'z';
char* c2 = 'w';
string s1{c1};
string s12{c1, c2};

- 226
- 1
- 11
-
The question is about converting a `char*` to a `std::string`. Where is the `char*` in your code? – Adrian Mole Jul 15 '22 at 03:29
-
-
1
-
-
2Really? When I try compiling your code, I get: **error : cannot initialize a variable of type 'char *' with an rvalue of type 'char'** – Adrian Mole Jul 16 '22 at 06:34
-
Not sure why no one besides Erik mentioned this, but according to this page, the assignment operator works just fine. No need to use a constructor, .assign(), or .append().
std::string mystring;
mystring = "This is a test!"; // Assign C string to std:string directly
std::cout << mystring << '\n';

- 3,449
- 6
- 42
- 59
-
2It does seem to work functionally, but when I did this I started getting issues with Valgrind reporting reachable blocks at the end of the program, originating from a "new" inside of `=` (and `+=`). It doesn't seem to happen with literals like this, but just with `char*` things. The issue of whether such reports are *actually* leaks are [discussed here](http://stackoverflow.com/q/2996498/211160). But if I changed the assign to `destString = std::string(srcCharPtr);` the valgrind leak reports went away. YMMV. – HostileFork says dont trust SE Nov 14 '14 at 16:26
-
HostileFork's comment might lead you to believe that constructing a string from a char* (like from fgets) will make std::string manage the lifetime of this memory. However this is not the case. See the standard 21.4.2.7 and .9 `Constructs an object of class basic_string and determines its initial string value from the array`. It says value and nothing about buffers or pointer ownership. – Erik van Velzen Mar 22 '15 at 23:27