文字列とSTL

発端


ドーナツの疑問より。

str.push_back("01234");
str.push_back("56789");
ってすると、
str[0]='0';
str="0123456789";
になると思ってたんだよね。
動的に要素を増やすわけだから、
str[0][0]='0';
str[0]="01234";
なわけですな。
となると、文字列"0123456789"を得たかったらどーしたらいいんだろうか?

以下俺なりの回答


std::ostringstream による方法

文字列を操作して、文字列に書き込むには、
Cならsprintfなんかを使うが、C++ だと std::ostringstream を使う。
使用例はこんな感じ。

#include <iostream>
#include <sstream> // stringstream用

int main(int, char**)
{
  std::ostringstream ostr;
  ostr << "01234"; // 追加はこんな感じ
  ostr << "56789";
  std::cout << ostr.str() // str() で std::string 型の文字列を取り出せる。
}

std::vector による方法


ドーナツのやろうとしていた、std::vectorを使った方法は、以下のような感じになる。
ただし、std::vectorではなくstd::vectorを使った。
頑張ってstd::vectorでやろうとすると、自力で1個クラスを作る羽目になる。


しかし、 std::vector は欠陥品だ。
一文字ずつしか取り出せないし、そもそも文字列として扱えないから。
それに、即値として"01234"なんかは使えない。追加するときには必ず宣言が必要。


しかし、ゲームのグラフィック周りなんかに使う場合は、
恐らく一文字ずつ扱うので問題にならないかもしれない。

#include <iostream>
#include <vector>

char A[] = "01234"; // 宣言しないとポインタが分からない。
char B[] = "56789";

int main(int, char**)
{
  std::vector<char> str;  // char*ではなくchar 
  str.insert(str.end(), A, A+5); // *A = "0" から *(A+5) = "\0"の直前まで追加。
  str.insert(str.end(), B, B+5);

//std::cout << str;  // エラーになる

  // 結局1文字ずつしか扱えない。
  for(std::vector<char>::iterator i = str.begin(); i != str.end(); ++i){
    std::cout << *i;
  }
}

std::string による方法


最後の手は、std::string を使うこと。

#include <iostream>
#include <string>

int main(int, char**)
{
  std::string str;
  str += "01234";  // += で string, char*, char が自由に結合できる。
  str += "56789";
  std::cout << str;
}

俺はこれがイチバン好き。