4

私はこのコードを持っています.CBStringは、何らかの処理に使用する単なる文字列クラスです

  char * scrummyconfigure::dosub(strtype input)
  {
    CBString tstring;
    tstring = input;
    uint begin;
    uint end;

    begin = tstring.findchr('$');
    end = tstring.findchr('}',begin);        

    CBString k = tstring.midstr(begin+2,end-2); // this is BASE
    strtype vname = (strtype) ((const unsigned char*)k);
    strtype bvar = (strtype) "BASE";
    assert(strcmp(bvar,vname) == 0); // this never fails
    // theconf is just a struct with the map subvars
    // subvars is a map<const char *, const char *>
    out(theconf->subvars[bvar]); // always comes up with the value
    out(theconf->subvars[vname]); // always empty

    uint size = end - begin;
    tstring.remove(begin, size);

    return (const char *)tstring; // it's OKAY! it's got an overload that does things correctly
    //inline operator const char* () const { return (const char *)data; } <-- this is how it is declared in the header of the library
  }

strcmp が常に文字列が同じであると言うのに、bvar として宣言した変数だけが何かを返すのはなぜですか?

4

3 に答える 3

5

文字列が同じだからといって、 std::map がそれらを同じキーとして扱うわけではありません。これは、std::map で使用される Compare クラスに依存します。デフォルトはless<KeyType>- であり、より小さい演算子を適用した場合と同じ結果が得られます。

operator()strtypes で適切な比較を行うように定義するクラスを定義し、それを std::map を定義するときに 3 番目のテンプレート引数として渡すことができます。または、提案されているように、std::string を strtype として使用します。

于 2012-07-26T00:29:20.543 に答える
5

//subvars はmap<const char *, const char *>

このマップのキーは文字列ではなく、メモリ アドレスです。対応するチェックは

assert( bvar == vname);

これはおそらく失敗します。キーの型を文字列クラスに変更する必要があります (std::stringまたはCBStringマップを意味のあるものに使用するため)。

于 2012-07-26T00:23:06.420 に答える
5

strtypeは次のように定義されていると仮定します。

typedef char * strtype

あなたの問題は、 vname と bvar が同じ値を持っていると仮定していることです。実際には、それぞれが同一のデータを含むメモリのブロックを指す異なる値を持っています。

std::mapばかげて == と比較していますが、それらを == と比較すると、予想どおり false になることがわかると思います。std::stringクラスを使用していないのはなぜですか?

編集:私はあなたの方法を書き直して、怖くないようにしました:

// implied using namespace std;
string ScrummyConfigure::removeVariableOrSomething(string tstring)
{
    uint begin; // I'll assume uint is a typedef to unsigned int
    uint end;

    begin = tstring.find('$', 0);
    end = tstring.find('}', begin);        

    string vname = tstring.substr(begin + 2, end - 2); // this is supposedly BASE
    assert(vname == "BASE"); // this should be true if vname actually is BASE

    out(this->conf->subvars[bvar]);  // wherever theconf used to be, its now a member
    out(this->conf->subvars[vname]); // of ScrummyConfigure and its been renamed to conf

    uint size = end - begin;
    tstring.erase(begin, size);

    return tstring; // no casting necessary
}
于 2012-07-26T00:23:24.763 に答える