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
標準では、コンストラクタパラメータは「nullポインタであってはならない」とあり、例外がスローされることを指定していません。

24
浅いコピーですか、深いコピーですか?

4
@pushkinいいえstrは単なる変数名です。それは何もすることができますSabclIstrHelloWorld。明らかに、いくつかの選択肢は他のものよりも優れています。しかし、この例でstrはかなり受け入れられます。
2016年

10
@Madhatterそれは深いコピーです。ポインタの割り当てはそのまま残り、文字列自体が新しい割り当てになります。
moodboom 2017

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 2011

2
int size = strlen(data);
ヴラド

@vlad:アイデアは、他のソースやデータからのサイズがC文字列ではないことを知っているということです(nullが埋め込まれているか、nullで終わっていない)。C文字列がある場合は、単にmyString = dataを実行できます。strlenまたは同等のものを実行します。
ユージーン

1
@huseyintugrulbuyukisik元のメモリを適切に破棄する必要があります。std:: stringはバイトをコピーしますが、所有権は取得されません。
ユージーン

2
@ZackLeeは、バイトに新しいメモリを割り当て、それらをすべてそこにコピーします。浅いコピーの可能性が必要な場合は、あるstd :: stringを別のstd :: stringにコピーする必要があります。次に、一部の実装では、浅いコピーを実行できると思います。
ユージーン

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*
スティーブジェソップ

1
右、c_str()を介してstd :: stringのデータを変更することはできません(すべきではありません)。データを変更する場合は、c_str()からのc文字列をmemcpyする必要があります
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を使用できます。

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
これらの2行だけで、data初期化されていない(空の)ままになります。
heltonbiker

1
提供されるポインターの真の「長さ」がないと、このコードによりデータが失われる可能性があり、std :: stringは元のcharよりも「短く」なります*
Andiana

0

エリック以外の誰もこれについて言及しなかった理由はわかりませんが、このページによると、代入演算子は問題なく機能します。コンストラクタ、.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を信頼してはならないと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 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.