2

私の弱点の 1 つは、C++ で char を効果的に使用することです。これは、私が現在やろうとしていることです。ゲームにプレーヤー クラスがあり、プレーヤー クラス内で、さまざまな情報を表示する playerCard オブジェクトを作成します。これは、プレーヤー オブジェクト (つまり、プレーヤー プレーヤー) の 1 つのインスタンスに対しては正常に機能しますが、プレーヤー オブジェクトをベクターに push_back しようとすると、すべてがうまくいきません。

基本的に、プログラムは引き続き実行されますが、プレーヤーは画面にレンダリングされません。プログラムを終了すると、main が MSG を返そうとするとブレークポイント エラーが発生します。ブレークポイントに関するコメントは次のとおりです。

    /*
     * If this ASSERT fails, a bad pointer has been passed in. It may be
     * totally bogus, or it may have been allocated from another heap.
     * The pointer MUST come from the 'local' heap.
     */
    _ASSERTE(_CrtIsValidHeapPointer(pUserData));

ここにエラーを見つけました

    strcat(nameCard, nameChar);
    strcat(nameCard, genderChar);
    strcat(nameCard, ageChar);
    strcat(nameCard, cashHeldChar);
    strcat(nameCard, productWantedChar);

これをコメントアウトすると、エラーが発生しないためです。ここに完全な playerCard クラスがあります (繰り返しますが、これは面倒で、おそらく物事を進めるには間違った方法ですが、文字/文字列などを使用して理解を深めようとしています) #include "Headers.h";

class Playercard{

private:

    RECT textbox;
    LPD3DXFONT font;

    std::string nameStr;
    std::string genderStr;
    std::string ageStr;
    std::string cashHeldStr;
    std::string prodWantedStr;

    char nameCard[1000];

public:

    Playercard()
    {
    }

    void load(char* name, bool male, int age, double cash, char* prod)
    {

        if(male)
        {
            genderStr = "Gender: Male\n";
        }
        else
        {
            genderStr = "Gender: Female\n";
        }

        nameStr = "Name: " + static_cast<std::ostringstream*>( &(std::ostringstream() << name))->str() + "\n";
        ageStr = "Age: " + static_cast<std::ostringstream*>( &(std::ostringstream() << age))->str() + "\n";
        cashHeldStr = "Cash Held: " + static_cast<std::ostringstream*>( &(std::ostringstream() << cash))->str() + "\n";
        prodWantedStr = "Product Wanted: " + static_cast<std::ostringstream*>( &(std::ostringstream() << prod))->str() + "\n";

        char * nameChar = new char [nameStr.length()+1];
        char * genderChar = new char [genderStr.length()+1];
        char * ageChar = new char [ageStr.length()+1];
        char * cashHeldChar = new char [cashHeldStr.length()+1];
        char * productWantedChar = new char [prodWantedStr.length()+1];

        strcpy(nameChar, nameStr.c_str());
        strcpy(genderChar, genderStr.c_str());
        strcpy(ageChar, ageStr.c_str());
        strcpy(cashHeldChar, cashHeldStr.c_str());
        strcpy(productWantedChar, prodWantedStr.c_str());

        strcat(nameCard, nameChar);
        strcat(nameCard, genderChar);
        strcat(nameCard, ageChar);
        strcat(nameCard, cashHeldChar);
        strcat(nameCard, productWantedChar);

        diagFile.open("Diag.txt");
        diagFile.write("Test", 100);
        diagFile.close();
    }

    void setUp(int L, int T, int R, int B)
    {
        SetRect(&textbox, L,T,R,B);
    }

    void draw()
    {
        font->DrawTextA(d3dSprite, nameCard, -1, &textbox, DT_LEFT, D3DCOLOR_XRGB(255, 255, 255));
    }

    LPCSTR plCard()
    {
        return nameCard;
    }
};

どんな助けでも大歓迎です。ありがとうございました。

4

2 に答える 2

2

あなたの主な問題は、初期化されていないことnameCardです。strcat魔法のように null で終わる文字列が必要であり、最初の文字または任意の文字nameCardが null であるという保証はありません。

ただし、C 文字列は不要です。いつも使っstd::stringてください。nameCard文字列に変更した後、次のように変更loadします(ファイル書き込みは除く):

void load(const std::string &name, bool male, int age, double cash, const std::string &prod)
{
    nameStr = "Name: " + name + "\n";
    genderStr = "Gender: " + (male ? "Male" : "Female") + "\n";
    ageStr = "Age: " + std::to_string(age) + "\n";
    cashHeldStr = "Cash Held: " + std::to_string(cash) + "\n";
    prodWantedStr = "Product Wanted: " + prod + "\n";

    nameCard = nameStr + genderStr + ageStr + cashHeldStr + prodWantedStr;
}

実際にはnameCard、データ メンバーを作成し、他のメンバーを削除して、これを使用します。

nameCard.clear();
nameCard += "Name: " + name + "\n";
//add on other parts

それ以外はplCard()return astd::stringにして in draw(), use nameCard.c_str(). 文字列で何ができるかがもう少し明確になることを願っています。

ただし、これstd::to_stringは C++11 であることに注意してください。C++03 には、次の 2 つの一般的なソリューションがあります。

std::string str = boost::lexical_cast<std::string>(someNumber);

または

std::ostringstream oss;
oss << someNumber;
std::string str = oss.str();

1 ライナーや 2 ライナーよりも 3 ライナーの方がはるかに読みやすいと思います。

于 2013-02-03T21:11:38.820 に答える
2

あなたnameCardは初期化されていません。最初のものstrcatstrcpyに置き換えるか、ゼロ文字列で初期化します。

std::stringでは、排他的に使用するのはどうでしょうか。

于 2013-02-03T21:00:58.583 に答える