2015年1月12日月曜日

C++再入門①_文字列操作編

C++、一度覚えたけど、結局C言語で事足りる事が多かったため、
使わないでいたら忘れたので、復習。

実行環境はwin7 x64 visual studio 2012

using namespace std;
とは何か?
using namespace std;の是非


using namespace std;を宣言した場合。





using namespace std;を宣言しなかった場合。



coutはprintfに相当(標準出力)
endlは改行


system("pause");
はコンソールを一時停止してくれる便利な奴。(windows以外で使えるかは不明。)
#include <windows.h>
のインクルードを必要とする場合がある。

system("pause>NULL");
とすると「続行するには……」が表示されなくなる。

実行結果





coutによる出力は以下の様に分けて書く事もできる。
また標準入力はscanfの代わりにcinを用いる。データ形式はstd::string。
ただし、「using namespace std;」と宣言しているため、単に「string」と書けばよい。

キーボードで文字を入力すると、Enterまでの文字列を返す。

実行結果




さて、この辺りまでは、別に何ともないだろう。
話しがややこしくなってくるのは、std::string形式をcharの配列として渡したい場合などだろう。

例えば、[std::string型] を [char配列] に変換して、printfに渡すには、
「const char*   std::string::c_str(   std::string   )」を用いれば良い。

[std::stringstream型] を [char配列]     に変換する場合は、
[std::stringstream型]   を [std::string型] に変換し、
さらに変換した
[std::string型]            を [char配列]      に変換する。
つまり、「const char*   std::string::c_str(   std::string   )」とさらに
「std::string   std::stringstream::str(   std::stringstream   )」を使えば良い。

以下に具体例を示す。


実行結果



逆の手順を考えてみよう。つまり、
①char配列をstd::string型に変換する。
とか、
②char型をstd::stringstream型に変換する。
あるいは、
③std::string型をstd::stringstream型に変換する。
の場合を考える。


①char配列をstd::string型に変換する。
「=」演算で変換できる。

上記の例の
string str;
str = "Hello C Plus Plus World!!";
そのものである。
納得がいかなければ、
string str;
char c_str[ ] = "Hello C Plus Plus World!!";
str = c_str;
として試してみればいい。

追記:いや、あるいは、
string str;
char c_str[ ] = "Hello C Plus Plus World!!";
str = std::string(c_str);
だったかも。

②char型をstd::stringstream型に変換する。
「<<」演算で変換できる。

同様に上記の例で
ss << "Hello C Plus Plus World!!";
にあたる。


③std::string型をstd::stringstream型に変換する。
「<<」演算で変換できる。

上記には無いが、
string str;
stringstream ss;
ss << str;
で普通に変換できる。


このように、逆の変換手順の場合は、特別な関数を必要とせずに変換ができる。
つまり、
stringstream > string > char配列
の順番で、左の型は右の型を自在に使用できる。



文字列を決まった文字数に丸めたりするには、
std::setw()   :  幅を指定する。
std::setfill()  :  空欄を何で埋めるかを指定する。(指定しなければ空欄で一文字となる。)
を用いればよい。


実行結果


オマケ。

classの基本的な書き方は、以下のようになる。



良く分かっていない事。
std::vector<char> str;

string型
と同じ?

「vector配列 c++」でGoogle検索
手を動かしてさくさく理解するC++ 動的配列クラス std::vector 入門
上記サイトによると、stringstreamとか、宣言時に最低限必要なサイズを教えておく事ができるので、やった方がいいらしい。
(結局プログラマーが自分で配列のサイズが足りるか確認して、足りなければ、内部的にはreallocとかで再確保するのだろうから、連続した領域にメモリを確保できるだけのスペースが無ければ、再確保のために、より広い連続したメモリ空間にデータを全てコピーする事から始まるのだから、当然と言えば当然。そもそも、足りないメモリ領域を追加するだけでも処理が発生する。)

そう言えばメモリって部分的に開放できないのか考えた事があるが、OSにメモリ管理APIなるものが存在するらしい。(首を突っ込むのはやめておこう。)

stringstreamに関しては、上記サイトの内容から、部分的に開放したりできるみたい。たぶん。


//
stringstreamで一文字ずつ読み込んだり、一行ずつ読み込んだりする方法の説明がされているページ。
http://program.station.ez-net.jp/special/handbook/cpp/stream/read.asp


//

coutの出力をstd::stringstreamだと思って使ったら、上手く出力できず。
coutはstd::stringなので、

stringstream ss;
ss << "TEST";
cout << ss.str() << endl;

とする必要がある。



//
#include <strings.h>←「man string」
#include <string.h>←「man memset」
#include <string>←std::stringを使うとき、これじゃないとエラーを吐いたような……???
って同じなのか?違うのか?

0 件のコメント:

コメントを投稿