DATE : 2006/09/29 (Fri)
C++ で文字列を扱うには、標準C++ライブラリの string クラスを使用します。C と同じように char 型の配列としても扱えますが、ここでは string クラスを使った方法を取り上げます。
文字列の静的な宣言
string クラスを使用するには、まず string ヘッダを取り込む必要があります。
#include <string>
string オブジェクトを文字列リテラルで宣言するには、次のようにします。
std::string str = "string";
なお、「string」の前にある「std」は「名前空間」です。string クラスは std 名前空間に属しているので、上のように書きます。Java で言えば、次のようなコードに相当します。
java.lang.String str = "string";
Java の場合、java.lang パッケージは自動的にインポートされるので、上のように java.lang と書く必要はありません。
ただし、C++ の場合でも、あらかじめ使用する名前空間を宣言しておくことで、クラスの名前空間を省略できます。
例えば、ファイル中で std 名前空間を使用するときは次のように書きます。
using namespace std;
これは、Java の場合は次のようなコードに相当します。
import java.lang.*;
ちなみに、名前空間の表記を特定のクラスのみ省略する場合は、次のように書きます。
using std::string;
これは、Java の場合は次のようなコードに相当します。
import java.lang.String;
文字列の動的な生成
Java では、+演算子を使うことで文字列を結合できます。
String str = "str" + "ing";
string オブジェクトも、+演算子で文字列を結合できます。ただし、文字列リテラル同士はアドレス同士の加算となるので、結合できません。そのため、string オブジェクトを作成した上での加算となります。
string s1 = "str"; string s2 = "ing"; string str = s1 + s2;
もしくは、次のようにも書けます。
string str = string("str") + string("ing");
また、文字列ストリームを使う方法もあります。
文字列ストリームを使うには、sstream ヘッダを取り込みます。
#include <sstream>
文字列ストリームを使って文字列を生成するコードを以下に示します。
std::ostringstream stream; stream << "str" << "ing"; std::string str = stream.str();
サンプルコード
ここで、 Point クラス、Line クラス に、オブジェクトの情報を文字列として返す toString メソッドを作ります。
(;^ω^)本当は、実際に点や線を描くメソッドを設けた方がそれらしいのですが、簡単のために文字列にしました。
追加したコードは次の通りです。
#include <string> #include <sstream> using std::string; using std::ostringstream; class Point { private : int x; int y; public : Point(); Point(int x, int y); Point* clone() const; int getX() const; int getY() const; string toString() const; }; Point::Point() : x(0), y(0) { } Point::Point(int x, int y) : x(x), y(y) { } Point* Point::clone() const { return new Point(this->x, this->y); } int Point::getX() const { return this->x; } int Point::getY() const { return this->y; } string Point::toString() const { ostringstream stream; stream << "(" << (this->x) << ", " << (this->y) << ")"; return stream.str(); } class Line { private : const Point *start; const Point *end; public : Line(const Point* start, const Point* end); Line(const Line& line); ~Line(); Line& operator=(const Line& line); const Point& getStart() const; const Point& getEnd() const; string toString() const; }; Line::Line(const Point* start, const Point* end) : start(start), end(end) { } Line::Line(const Line& line) : start(line.getStart().clone()), end(line.getEnd().clone()) { } Line::~Line() { delete this->start; delete this->end; } Line& Line::operator=(const Line& line) { if (this == &line) { return *this; } delete this->start; delete this->end; this->start = line.getStart().clone(); this->end = line.getEnd().clone(); return *this; } const Point& Line::getStart() const { return *(this->start); } const Point& Line::getEnd() const { return *(this->end); } string Line::toString() const { ostringstream stream; stream << (this->start->toString()) << " - " << (this->end->toString()); return stream.str(); }
変更した部分は、次の通りです。
#include <string> #include <sstream> using std::string; using std::ostringstream;
class Point { private : int x; int y; public : Point(); Point(int x, int y); Point* clone() const; int getX() const; int getY() const; string toString() const; };
string Point::toString() const { ostringstream stream; stream << "(" << (this->x) << ", " << (this->y) << ")"; return stream.str(); }
class Line { private : const Point *start; const Point *end; public : Line(const Point* start, const Point* end); Line(const Line& line); ~Line(); Line& operator=(const Line& line); const Point& getStart() const; const Point& getEnd() const; string toString() const; };
string Line::toString() const { ostringstream stream; stream << (this->start->toString()) << " - " << (this->end->toString()); return stream.str(); }
このようにしておくと、次のように Line オブジェクトの情報を toString メソッドを呼び出すだけで取得することができます。
Line line(new Point(0, 0), new Point(10, 10)); std::cout << line.toString() << std::endl;
上のコードを実行すると、次のように表示されます。
(0, 0) - (10, 10)