0

intまたは文字列「all」を受け取り、対応する出力を出力する単純な関数printNodeを作成しています。関数の int の側面はうまく機能しますが、呼び出すと

printNode all

関数は「エラー:無効な引数」を出力しますが、その理由がわかりません。

int main() {
    ...
    getline(cin, line)
    stringstream lineStream(line);
    stringstream elineStream(line);
    printNode(lineStream, elineStream);
    ...
}


int printNode(stringstream& lineStream, stringstream& elineStream) {
//String aspect of printNode
int nodeid;
string name;

// Parsing nodeid or name
lineStream >> nodeid;

// If parsing to nodeid fails, check if input is string "all"
if (lineStream.fail()) {
    elineStream >> name;
    if (elineStream.fail()) {
        if (elineStream.eof()) {
            cout << "Error: too few arguments" << endl;
            return 0;
        }
        else {
            cout << "Error: invalid argument" << endl;
            return 0;
        }
    }
    if (name != "all") {
        cout << "Error: invalid argument" << endl;
        return 0;
    }
    // Check for too many arguments
    elineStream >> ws; 
    if (!elineStream.eof()) {
        cout << "Error: too many arguments" << endl; 
        return 0;
    }

    // Print output for input "all" 
    cout << "Print: all nodes" << endl;
    return 1;
}

どんな助けでも大歓迎です。

4

2 に答える 2

0

あなたはそれprintNode allを入力として与えていますが、期待しているのはall. 私はあなたのコードを試してみましたが、正しく動作します (もちろん、printNode all無効な引数で失敗します)。

ちなみに、最初のストリームのエラー フラグをクリアするだけで、2 つのストリームの使用を回避できたはずです。つまり、数値の読み取りに失敗したことがわかった後に追加するelineStreamだけで済みます。lineStreamlineStream.clear();


あなたの言い回しから、私も明確にしたい奇妙なことがわかります(念のため):

しかし、私が電話するとき

printNode all

コマンドラインに書き込むことで、関数を呼び出していません。次のように記述すると、関数が呼び出されます。

printNode(lineStream, elineStream);

あなたのソースコードで。コマンド ラインで を記述した場合、printNode allその文字列のすべて (行全体を読み取ったため) だけでなく、ストリームに転送されますall

于 2013-10-04T15:36:17.090 に答える
0

「コマンド」とそのすべてのオプションを取得する簡単な方法があります。 std::copywithstd::istream_iteratorstd::back_inserterを使用してすべての単語をstd::vector. 次に、ベクトルのサイズを単純にチェックして、コマンドが有効かどうかを確認します。

これを何か行:

std::vector<std::string> command_and_args;

std::copy(std::istream_iterator<std::string>(lineStream),
          std::istream_iterator<std::string>(),
          std::back_inserter(command_and_args));

if (command_and_args.size() == 0)
    std::cout << "Error: No command or arguments\n";
else if (command_and_args.size() == 1)
    std::cout << "Error: To few arguments\n";
else if (command_and_args.size() > 2)
    std::cout << "Error: To many arguments\n";
else
{
    // Got the command and one argument
    // Command in `command_and_args[0]`
    // Argument in `command_and_args[1]`
}

パーツはすべてのstd::copyコマンドに使用できますが、チェックは個別にする必要があります。


編集:std::function実際には、コマンドの詳細を示す構造体を作成すると、引数の数のチェックも自動化できます(コマンド文字列、引数が必要かどうかを伝えるブール値、引数の最小数、引数の最大数、およびコマンド ハンドラー)。この構造でテーブルを作成し、それを調べてコマンドを見つけ、引数の数をチェックし (必要な場合)、関数オブジェクトを呼び出します。次に、関数オブジェクトは個々の引数をチェックできます。

于 2013-10-04T15:36:57.400 に答える