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)
