入力文字列から数字と文字を分離するのに問題があります。私のプログラムの目的は、後置で足し算、引き算、掛け算、割り算を行うことなので、入力フォームは2 2 3 + * (答えは 10)から2 2 + 3 * (答えは 12) まで予測できません。 . そのため、sscanf を使用して、入力文字列に特定の形式を指定せずに数字と演算子文字を抽出することはできません。ここで何をすべきですか?
4 に答える
Postfix を処理するには、スタックを実装する必要があるため、取得した各数値をスタックにプッシュする必要があります。各演算子はスタックから 2 つポップし、結果をプッシュします。
1 つの方法はscanf("%s")
、次の空白までの文字を返す which を使用することです。getc
または、文字を 1 つずつ取得するために使用することもできます。
編集:
get を使用しているコメントから、行全体を読み取ることができます。その場合、ループでstrtokを使用して行をトークンに分割し、各トークンの最初の文字を見て何を決定するかを決定する方がよい場合があります。それを行うために。
char line[MAX_LINE];
// read in the line
char * pTok = strtok(line, " \t");
while (pTok)
{
char ch = pTok[0];
if (isdigit(ch))
//handle number
if (ch == '+')
//handle addition operator
...
pTok = strtok(NULL, " \t");
}
おそらく、行全体を取得してから、文字列、オフセット、および戻り構造体を受け取る関数を作成することでこれを行うでしょう。戻り構造体には、トークンの開始オフセットと終了オフセット、トークン タイプ (演算子、引数)、および場合によってはその他の要素が含まれます。
または、数値をチェックする関数と演算子をチェックする関数の 2 つの関数に分割します。
Boost.Spirit Qi を使用することをお勧めします。これは非常に優れたパーサー ライブラリです。最初の例は電卓です...
http://www.boost.org/doc/libs/1_42_0/libs/spirit/doc/html/spirit/introduction.html
標準ライブラリのみのソリューション:
// Get a line of user input (simplifies I/O)
std::string line;
if (!std::getline(std::cin, line)) throw std::runtime_error("Unable to read line");
// Process the line as an input string stream
std::istringstream iss(line);
while (true) {
unsigned int val;
if (iss >> val) {
// TODO: Handle a numeric value (in val)
continue;
}
iss.clear(); // Clear the error state
char ch;
if (!iss.get(ch)) break; // Break the loop if there is no more input
// TODO: Handle a character (in ch)
}