みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C++の問題で・・

C++の問題で・・

参考書に「簡易的な文字列クラスStringを作成せよ。」という問題があり作りました。
いかにそのコードを示します。今回の質問の内容に関係ないとおもうところや、インクルードなどは省かせていただきます。
環境は Visual studio 2008です。OSはXPです。

class String{
    int len;//文字列の長さ
    char *s;//文字列の先頭文字へのポインタ
public:
    String(const char *);
    int length()const{return len;}//長さを求める
    operator const char * ()const{return s;}
    bool operator==(String &a)const{return strcmp(this->s, a);}
    char *operator+(String&)const;
};


char * String::operator +(String &a)const
{
    char *memory = new char[this->len + a.len + 1];
    memory[0] = '\0';
    return strcat(strcat(memory, this->s), a);
}

String::String(const char *p): s(const_cast<char *>(p)), len(strlen(p)){}

String::String(const String &x)
{
    s = x.s;
    len = x.len;
}

inline std::ostream& operator<<(std::ostream &s, String &x)
{
    return s << static_cast<const char *>(x);
}

int main()
{
    String a("My name is Paul");
    String b("My name is Paul");
    String c("My name");
    String d(" is Paul");

    cout << "a = " << a << "\n";
    cout << "b = " << b << "\n";
    cout << "c = " << c << "\n";
    cout << "d = " << d << "\n";

    cout << "a == b " << (a == b) << "\n";
    cout << "a == c " << (a == c) << "\n";
    cout << "c + d = " << (c + d) << "\n";
}    


このようなプログラムなのですが、上記の
char * String::operator +(String &a)const
{
    char *memory = new char[this->len + a.len + 1];
    memory[0] = '\0';
    return strcat(strcat(memory, this->s), a);
}
ところで、 memory[0] = '\0'; を除くと文字列を出力した結果をみると、先頭にいらない言葉が入っています。
僕の場合は x9My name is Paul と表示されます。文字化け・・ではないのですが、ゴミのようなものが・・

どうしてこのようなことが起こるか、どこでゴミが入ってしまうのか教えてほしいです。

稚拙なプログラムで申し訳ないです。
もし、間違っている場所や、もっと簡単にかけるようなところがあれば、ご指摘いただくとありがたいです。

よろしくお願いします!

投稿日時 - 2010-06-02 01:48:50

QNo.5938693

困ってます

質問者が選んだベストアンサー

本題自体は #1 でも言われるように「strcpy と strcat の違いを理解しろ」ってことなんだけど....
ついでにコメント:
・引数が String & になっているのが多いけど, なぜ const String & にしないの?
・String::operator + の結果は String にすべきだと思う. そうじゃないと a+b+c で楽しいことがおきる.
・String::operator == がおかしい.

投稿日時 - 2010-06-02 12:41:08

お礼

下の方の回答でstrcpyとstrcatの使い分けがわかりました。
ありがとうございます。

あぁ・・確かにconst参照にしたほうがいいですね!
何かまだconstをつける習慣、というんですか、constの発想が毎回はできないみたいです・・。

本当ですね・・・楽しいことがおきました(笑)
char * で返していたらもう一回の連結のときは連結方法がわからない状況になるから、型名を返したほうがいいんですね

うーん・・どこがおかしいのかよく分からないです・・。ごめんなさい。
int型からbool型に暗黙的に変換されているところですか?
ここだったら、0以外はtrueになるかなぁと思ってこうしておきました

おかしいところを指摘していただいてありがとうございました!

投稿日時 - 2010-06-02 22:38:00

ANo.2

このQ&Aは役に立ちましたか?

7人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

String::operator == の話だけですが, strcmp は「等しいとき」に 0 を返しま
す. だから, 現状 String::operator == は等しいときに false を, 等しくない
ときに true を返します.

投稿日時 - 2010-06-03 01:00:25

ANo.1

> どうしてこのようなことが起こるか、どこでゴミが入ってしまうのか教えてほしいです。

> char *memory = new char[this->len + a.len + 1];
 C++ではnewで配列領域を確保しただけでは初期化はされません。したがって最初からゴミが入っています。

> return strcat(strcat(memory, this->s), a);
 ゴミが入った領域にstrcatで文字列を追加してるのだから、先頭にゴミが入ります。

 普通は以下のようにするでしょうね。

 return strcat(strcpy(memory, this->s), a);

投稿日時 - 2010-06-02 02:48:10

お礼

newで確保した配列は初期化されていないのですか・・
charの場合は先頭がNULLで初期化されているのだと思ってました。

だから、先頭のゴミの上から最初のをコピーして、次にそこに連結するんですね!
わかりやすく教えていただいてありがとうございます

投稿日時 - 2010-06-02 22:29:55

あなたにオススメの質問