std :: stringに文字を追加する方法は?


175

以下はエラーで失敗します prog.cpp:5:13: error: invalid conversion from ‘char’ to ‘const char*’

int main()
{
  char d = 'd';
  std::string y("Hello worl");
  y.append(d); // Line 5 - this fails
  std::cout << y;
  return 0;
}

コンパイル時に実行時にランダムに動作する次のものも試してみました:

int main()
{
  char d[1] = { 'd' };
  std::string y("Hello worl");
  y.append(d);
  std::cout << y;
  return 0;
}

この馬鹿げた質問で申し訳ありませんが、私はグーグルの周りを検索しました、私が見ることができるのは単に「char配列からchar ptr」、「char ptrからchar配列」などです。


コンパイラエラーはい。エラーの内容を忘れてしまいましたが、それは妥当です。
2009

3
以下でより良い答えがありますが、2番目の例をこの文字のように機能させることができますd [2] = {'d'、0}; または単にchar d [2] = "d"; 基本的に、追加するために渡すCスタイルの文字列を終了するには0が必要です
sbk

回答:


224
y += d;

+=名前付き関数の代わりに演算子を使用します。


2
+ = push_backよりも良いと考える理由は?タイピングが少ないのですか、それとも別の理由がありますか?
グレン

4
タイピングが少なくなります。ではgccbasic_string::operator+=はの呼び出しですpush_back
eduffy 2009

2
文字列の方がより自然なIMOです。push_backはコンテナ関数であり、文字列はSTLで特殊化されたものです:)
AraK

6
その質問を振り返ってみましょう:なぜpush = backは+ =よりも良いと思いますか?私の意見では、+ =は明確で簡潔です。
Jesper、

34
これに注意したいのは、習慣になった場合、yがのchar*代わりにであれば問題なくコンパイルされるためですstd::stringdポインタyに文字を追加します。
Zan Lynx


19

appendメソッドを使用してstd :: string varに文字を追加するには、次のオーバーロードを使用する必要があります。

std::string::append(size_type _Count, char _Ch)

編集:あなたの言うとおり、コンテキストヘルプに表示されているsize_typeパラメータを誤解しています。追加する文字数です。だから正しい呼び出しは

s.append(1, d);

ない

s.append(sizeof(char), d);

または最も簡単な方法:

s += d;

ここでは、sizeofの使用は意味的に正しくないと思います(sizeof(char)は常に1であるため、たまたま機能します)。同じキャラクターのコピーをさらに追加したい場合は、appendメソッドがより便利です!!!!!!!!!!
UncleBens 2009

1
sizeof(char)代わりになぜ使用しています1か?の繰り返しを1つdだけ追加したいので、そのように言います。使用してsizeof、それが1を伝えるために持っていることを示唆しているので、ここでは、誤解されるappend(そうではありません)に使用されるデータ型のバイトサイズを。
Ferdinand Beyer

Unclebensが言ったように、同じ文字を何度も追加する場合は、appendメソッドが本当に便利です。
Patrice Bernassola

10

言及された他のものに加えて、文字列コンストラクタの1つはcharとそのcharの繰り返し数をとります。したがって、これを使用して単一の文字を追加できます。

std::string s = "hell";
s += std::string(1, 'o');

7

いくつかの命題を大きなループで実行してテストします。マイクロソフトビジュアルスタジオ2015をコンパイラーとして使用し、プロセッサーはi7、8Hz、2GHzです。

    long start = clock();
    int a = 0;
    //100000000
    std::string ret;
    for (int i = 0; i < 60000000; i++)
    {
        ret.append(1, ' ');
        //ret += ' ';
        //ret.push_back(' ');
        //ret.insert(ret.end(), 1, ' ');
        //ret.resize(ret.size() + 1, ' ');
    }
    long stop = clock();
    long test = stop - start;
    return 0;

このテストによると、結果は次のとおりです。

     operation             time(ms)            note
------------------------------------------------------------------------
append                     66015
+=                         67328      1.02 time slower than 'append'
resize                     83867      1.27 time slower than 'append'
push_back & insert         90000      more than 1.36 time slower than 'append'

結論

+= より理解しやすいように見えますが、速度を気にする場合は、追加を使用してください


このような答えが意味を持つようにするには、LOTが異なる可能性があるため、使用しているコンパイラーを最小限に抑える必要があります。お使いのプロセッサーについて説明することも、実際の影響の大まかな見積もりを得るのに役立ちます。
akaltar

私はビジュアルスタジオ2015を使用しました。他のテストを実行するためにgccを探します。私のプロセッサはi7、8ハート、2.20 GHzです...しかし、私のプロセッサが何であっても、std :: stringの実装には影響しません...これらのメソッドの一部がマルチスレッドで、他のメソッドがそうでない場合を除きます。
Hugo Zevetel 2016

特にミリ秒単位でタイミングを表示している場合は特に、影響がある場合があります。代わりに、最速の方法に対する相対的なパーセンテージで表示することもできます(したがって、実際のプロセッサー速度は無関係です)また、そのデータをコメントから回答に移動します。これは一般的なStackExchangeのエチケットです。そうでなければいい答え。
akaltar 2016


2

の問題:

std::string y("Hello worl");
y.push_back('d')
std::cout << y;

char d = 'd'のように、charの名前を使用するのではなく、 'd'が必要です。それとも私は間違っていますか?


私はそれを試してみましたが、うまくいきました。私は持っておりchar c = 'd'y.push_back(c)問題なく行うことができます。したがって、問題はありませんstd::string::push_back()(ただし、がを超える場合を除き+=ます)。
フランクリンユー

1
int main()
{
  char d = 'd';
  std::string y("Hello worl");

  y += d;
  y.push_back(d);
  y.append(1, d); //appending the character 1 time
  y.insert(y.end(), 1, d); //appending the character 1 time
  y.resize(y.size()+1, d); //appending the character 1 time
  y += std::string(1, d); //appending the character 1 time
}

これらのすべての例では、文字リテラルを直接使用することもできますy += 'd';

あなたの2番目の例は、無関係な理由で、ほとんどうまくいったでしょう。char d[1] = { 'd'};動作しませんでしたが、char d[2] = { 'd'};(配列はサイズ2であることに注意してください)はとほぼ同じようconst char* d = "d";に動作し、文字列リテラル追加できますy.append(d);


1

dをポインターy.append(* d)として使用してみてください


シングルcharは文字列ではなく、null終止符がないため、これは危険です。これを行うと、未定義の動作が発生します。
Simon Kraemer 2016

これは間違っています。*dはポインターddはないため、構文エラーである逆参照ポインターを意味します。
フランクリンユー

0
str.append(10u,'d'); //appends character d 10 times

文字を追加したい回数に10ではなく10uを書いたことに注意してください。10を任意の数に置き換えます。


0

私は簡単な方法を見つけました... charその場で作られている弦に付け加える必要がありました。私は必要なchar list;私は、ユーザーに選択肢を与え、でその選択を使用していたのでswitch()声明。

私は単に別のものstd::string Slist;を追加して、新しい文字列を "list"-a、b、cまたはエンドユーザーが次のように選択したものに等しく設定しました。

char list;
std::string cmd, state[], Slist;
Slist = list; //set this string to the chosen char;
cmd = Slist + state[x] + "whatever";
system(cmd.c_str());

複雑さはクールかもしれませんが、シンプルさはクールです。私見では


0

まだ述べられていないように、挿入オプションも追加します。

std::string str("Hello World");
char ch;

str.push_back(ch);  //ch is the character to be added
OR
str.append(sizeof(ch),ch);
OR
str.insert(str.length(),sizeof(ch),ch) //not mentioned above

-1

push_backを使用している場合、文字列コンストラクターの呼び出しはありません。それ以外の場合は、キャストによって文字列オブジェクトを作成し、この文字列の文字を他の文字列に追加します。小さなキャラクターにはあまりにも多くのトラブル;)


1
演算子+ =(char c); 文字列に対してオーバーロードされます。実際、文字列コンストラクターは1文字を受け入れません。ブライアンの回答を参照してください;)
AraK
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.