1

私は現在、いわばコマンドライン「パーサー」を書いていますが、これまでのところ、オプション/パラメーターを追加するいくつかの方法を試すまでは機能していました。

void parser::nextCom() {

    cout << parser::prompt; // parser::prompt = "> "
    string com;
    getline(cin, com);

    char the_command[5]; //  i want this to store the command e.g. "go" given that go is a command
    for (int i = 0; i < com.size(); i++) {
        if (com[i] == ' ') break;
        else the_command[i] = com[i];
    }

    cout << the_command << endl;
}

the_commandコマンドはコピーされますが、コンソールに出力すると、非常に不要な文字が表示されます。

コマンドとして「北に行く」を渡すと、次のようになります。

goÌÌÌÌÌÌÌÌÌÌÌÌÌÌØNi

C++ の char 配列についてはよくわかりませんが、この出力を取得する方法がわかりません。どんな助けでも大歓迎です。コードに関する質問、または私のコードがさらに必要な場合は、コメントしてください。事前に感謝します

4

5 に答える 5

4
cout << the_command << endl;

このcharような配列を出力すると、文字列にヌル文字\0が見つかるまで文字が挿入され続けます。

comからへの文字のコピーを開始する前the_commandは、配列は完全に初期化されていません。これらの不明な文字は疑問符で表します (もちろん、実際には疑問符ではない可能性があります)。

? ? ? ? ?

charこれは、配列内の s の値がどうなるかわからないことを意味します。g次に、文字とofromのみthe_commandをにコピーするとcom、配列には以下が含まれるようになります。

g o ? ? ?

したがって、この配列を出力しようとすると、出力ストリームはいつ停止するかわかりません。\0の後に必ず を挿入する必要がありますo。それを行う1つの方法は次のとおりです。

for (int i = 0; i < com.size(); i++) {
    if (com[i] == ' ') {
      the_command[i] = '\0';
      break;
    }
    else the_command[i] = com[i];
}

これにより、配列は次のようになります。

g o \0 ? ?

ただし、 に固執する方がずっと良いでしょうstd::string。このアレイで発生するトラブルについては考えたくありません。関数の書き方は次のとおりです。

void parser::nextCom() {
    std::cout << parser::prompt;

    std::string command_line, command;
    std::getline(cin, command_line);

    std::stringstream command_line_stream(command_line);
    command_line_stream >> command;

    if (command == "go") {
      std::string direction;
      command_line_stream >> direction;
      go(direction);
    }
}
于 2013-03-21T20:19:33.377 に答える
3

the_command最後の文字が読み取られた後、nullで終了することはありません。または、境界チェックを実行します。

std::string代わりに使用してください。

于 2013-03-21T20:18:09.523 に答える
3

コードを次のように変更します。

if (com[i] == ' ')
{
   com[i] = '\0';
   break;
}

これにより、char配列の最後にnullターミネータが確実に存在します。ガベージが表示される理由std::coutは、nullターミネータが表示されるまで文字を喜んで印刷するためです。

于 2013-03-21T20:18:25.787 に答える
1

これは、コードにバッファ オーバーフローがあるためです。不確定な長さの文字列を char[5] バッファにコピーしました... 基本的に、ループは入力文字列によって決定された数のバイトを char[5] 配列の終わりを過ぎてコピーしています。したがって、「cout」は null バイトが見つかるまで読み取ります。

于 2013-03-21T20:15:21.097 に答える
1

the_command[5]は初期化されておらず、文字ターミネータが含まれていないため、基本的にガベージが含まれています。先にクリアしておけば大丈夫

for (i = 0; i < 5; i++)  {
    the_command[i] = 0; 
}
于 2013-03-21T20:18:59.447 に答える