C++ stringクラスをつかってみよう。

better Cになれているといつまでも新しいことが覚えれない。C++の機能をどんどん覚えていきたいと思います。今回はstringクラスについていろいろなサイトを見て回り勉強しました。

  • char型の配列では後で配列の長さを変えことができませんが、しかしstringクラスでは動的に確保できます。

string型の変換はこちらで

chocochoco.hatenablog.com

まず適当にソースを

#include<iostream>
#include<string>
using namespace std;

int main(){
//この初期化は見えている分は同じ動きをします。内部は少し違うらしいです。
string str1 = "str";
string str2("str");  

cout << str1 << endl;//結果"str"
cout << str2 << endl;//結果"str"

str1 = str2;

str1 += "1"; //結果"str1"
//str2 += "1" + "adddd"; //error 2つ以上はできません
//str2 += "2%s", str1; //もちろんだめ 結果"str2%s"
//str2 += ("2%s", str1); //もちろんだめ 2が無視されます 結果"strstr1"

cout << str1 << endl;//結果"str1"
cout << str2 << endl;//結果"str"

return 0;
}

 +=や=がありますがこれは演算子オーバーロードが行われています。この記事では説明しないので、他に調べてください。

 

stingはクラスなので便利なメンバ関数があります。それもとても多いです;;

(例) 返り値 関数名()  

※末尾にconstがついているものはその関数内でオブジェクトが変化しないことを保証されています。

  • size_type size() const おそらくバイト数を返しているのでしょう。
  • size_type length() const まぁ文字列の長さでしょう。ワイド文字は2文字分なので6になります。私の環境ではsize()と同じ挙動をしていますが、他はわかりません。

string str = "ハロー";

cout << str.size() << endl;//結果6
cout << str.length() << endl;//結果6 

  • const char* c_str() const  const char*を返してくれます。 strcat(char*, const char*)ではstringクラスは当然使えませんが、str.c_str()とすることで、第2引数に渡すことが可能になります。

char charStr[30] = "abc";

//strcat( charStr, str);//error
strcat( charStr, str.c_str());//strは”ハロー”が入っています。

cout << charStr << endl;//結果"abcハロー"

  • void clrear() 文字列を空にします。
  • bool empty()const 文字列が空ならtrueを返します。

string str = "abc";

str.clear();
cout << str << endl;//""  空白
cout <<str.length() << endl;//0 

cout <<str.empty() << endl;//1 

  • char& [size_type num] num個目の要素を返しますが、範囲外を参照できます。
  • char& at(size_type num) num個目の要素を返し、範囲外ならout_of_range例外を投げてくれます。

str = "01234";
cout << str[10] << endl; //何事もなかったかのように実行してしまう。バグに気づけない可能性がある。
cout << str.at(10) << endl; //out_of_range例外を投げてくれる。

  • size_type find(const char* str, size_type pos = 0)const pos番目からstr文字列と一致する地点を検索して返します。見つからなかった場合はnposを返します。
  • size_type rfind(const char* str, size_type pos = npos)const findの逆向き番、pos番目から逆順に検索します。pos = nposの場合、終点から逆向きに検索します。
  • string::npos 間違った説明したくないので難しいです。上で使うような特殊な数値。

cout << (int)string::npos << endl; //"-1"
cout << string::npos << endl; //"0xffffffff"

shift_jisでは全角文字に\が入っているのでfindでの検索にひっかかってしまいます。また全角の=を含む文字列に。を検索すると同じく引っかかります。unicodeなら大丈夫みたいです。

  • string& insert(size_type pos = 0, const char* str) 文字列のpos番目にstr文字列を挿入することができます。
  • string& erase(size_type pos = 0, size_type num = npos)  posの番目の位置からnum文字を消します。消した分はちゃんと詰めてくれます。numにnposを指定するとposから最後まで全部消します。
  • string& replace(size_type pos, size_type num, const char* str) オーバーロード
  • string& replace(size_type pos, size_type num, const string& str) pos番目からstrの文字列で置き換えます。何文字おきかえるかはnumで指定します。strの文字列はすべて挿入されます。

string str = "01234";

str.insert( 3, "in");
cout <<str << endl;//結果"012in34"
str.erase( 1, 2);
cout <<str << endl;//結果"0in34"

str.replace( 1, 2,"abcd");
cout <<str << endl;//結果"0abcd34"

  • void resize(size_type num) 文字列のサイズを変更できます。

string str = "012in34";

cout << str.size() << endl;//結果7

str.resize(5);
cout <<str << endl;//結果"012in"

cout << str.size() << endl;//結果5

  •  void reserve(size_type num = 0) 内部で動的に確保されるメモリの最低num サイズを保証します。

  • size_type capacity()const 内部で動的に確保されているメモリのサイズがわかります。

string str;
str.reserve(8);
cout << str.size() << endl;//結果0 
cout << str.capacity() << endl;

//結果15 8じゃなかった(笑) 最低値ですからね。

//reserveの引数を20にしたらcapacity()で31が50を入れたら63確保されていました。どうやら私の環境(64bitPC)では(2の倍数‐1)確保されるみたいです。

 参考: SophiaFramework UNIVERSE, C++入門, ロベールのC++