char *를 std :: string으로 변환


262

에서 std::string검색 한 데이터를 저장하려면를 사용해야합니다 fgets(). 이렇게하려면 char*반환 값을에서 fgets()std::string저장하여 배열에 저장 해야합니다 . 어떻게 할 수 있습니까?

답변:


376

std::string 이것에 대한 생성자가 있습니다 :

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

이 구문은에 문자 목록을 깊게 복사 s하고 s해서는 안됩니다 nullptr. 그렇지 않으면 동작이 정의되지 않습니다.


6
그렇다면 어떻게됩니까?
카슨 마이어스

14
표준에 따르면 생성자 매개 변수는 "널 포인터가 아니어야합니다"라고 말하고 예외가 발생하도록 지정하지 않습니다.

24
얕거나 딥 카피입니까?

4
@pushkin No str는 변수 이름입니다. 그것은 아무것도 될 수있다 : S, abc, l, I, strHelloWorld. 분명히 어떤 선택은 다른 것보다 낫습니다. 그러나이 예 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에 initialize가 있습니까? myString 변수가 채워질 때 간단히 선언합니까?
IcedDante

2
int 크기 = strlen (데이터);
Vlad

@ vlad : 아이디어는 다른 소스의 크기를 알고 있거나 데이터가 C 문자열이 아니라는 것입니다 (널이 있거나 널로 끝나지 않습니다). C- 문자열이 있다면 간단히 myString = data를 수행 할 수 있습니다. 그것은 당신을 위해 strlen 또는 동등한 것을 실행할 것입니다.
Eugene

1
@huseyintugrulbuyukisik 당신은 여전히 ​​원래 메모리를 올바르게 처분해야합니다-std :: string은 바이트를 복사 할 것입니다. 소유권을 가지지 않습니다.
유진

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

fgets ()로 검색 한 데이터를 저장하려면 std :: string을 사용해야합니다.

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이어야합니다.
Carson Myers

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

방금 std::string(char*)최상위 답변과 마찬가지로 생성자 를 사용하기 위해 MSVC2005로 고심하고 있습니다 . 필자가 항상 신뢰하는 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

1
포인터의 "길이"가 제공되지 않으면이 코드로 인해 데이터가 손실 될 수 있습니다. std :: string은 원래 문자보다 "더 짧습니다"
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는 SE 11:14

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.