0

私は文字列を持っていますstr ( "1 + 2 = 3" )。文字列の個々の数値を 10 進値で取得したい ( ASCII ではない)。私は試してみatoiましc_str()た。ただし、どちらも文字列全体が数字のみで構成されている必要があります。私は C++ でコードを書いています。

どんな助けでも素晴らしいでしょう。

私の課題は、接頭辞式を評価することです。各行にプレフィックス式が含まれているファイルから読み取っています。変数をトークン化して保存するためのコード スニペットを以下に示します。ファイルの各行には、スペースで区切られた数字と演算子 ( +-、 ) が含まれています。*

元 -line = ( * + 2 3 4);

    ifstream file;
    string line;

    file.open(argv[1]);
    while(!file.eof())
    {
            getline(file,line);
            if(line.length()==0)
                    continue;
            else
            {
                    vector<int> vec;
                    string delimiters = " ";
                    size_t current;
                    size_t next = -1;
                    do
                    {
                            current = next + 1;
                            next = line.find_first_of( delimiters, current );
                            if((line[next] <=57)&&(line[next] >=48))
                                   vec.push_back(atoi((line.substr( current, next - current )).c_str()));
                    }while (next != string::npos);
                    cout << vec[0] << endl;
            }
    }
    file.close();

この場合、 notvec[0]を出力します。502

4

3 に答える 3

4

文字列を区切る方法を学ぶ必要があります。区切り文字は数学演算子になります (つまり:

C: 区切られたソース文字列から文字列の配列を作成する

http://www.gnu.org/software/libc/manual/html_node/Finding-Tokens-in-a-String.html

2 番目のリンクの場合は、次のようにします。

const char delimiters[] = "+-=";

この知識があれば、文字列の配列を作成し、各文字列に対して atoi() を呼び出して、同等の数値を取得できます。次に、各区切り記号のアドレス (配列インデックス) を使用して、そこにある演算子を特定できます。

足し算や引き算などの場合、これは非常に簡単です。演算と乗算、括弧などの順序が必要な場合、プロセス フロー ロジックはより複雑になります。

より詳細な例については、この最後のリンクを参照してください。C で書かれたシンプルなコマンドライン計算機です。

http://stevehanov.ca/blog/index.php?id=26

于 2013-02-13T23:59:03.923 に答える
0

fin.eof()ループの制御には使用しないでください。この関数は、読み取りが失敗した後にのみ役立ちます。

intからsを取得する方法はいくつかありますがstd::stringstd::stoi()、この場合はC++11標準から選択しています。

#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>

typedef std::vector<int> ints;

bool is_known_operator(std::string const& token)
{
    static char const* tokens[] = {"*", "/", "+", "-"};
    return std::find(std::begin(tokens), std::end(tokens), token) != std::end(tokens);
}

ints tokenise(std::string const& line)
{
    ints vec;
    std::string token;
    std::istringstream iss(line);

    while (iss >> token)
    {
        if (is_known_operator(token))
        {
            std::cout << "Handle operator [" << token << "]" << std::endl;
        }
        else
        {
            try
            {
                auto number = std::stoi(token);
                vec.push_back(number);
            }
            catch (const std::invalid_argument&)
            {
                std::cerr << "Unexpected item in the bagging area ["
                    << token << "]" << std::endl;
            }
        }
    }
    return vec;
}

int main(int, const char *argv[])
{
    std::ifstream file(argv[1]);
    std::string line;
    ints vec;

    while (std::getline(file, line))
    {
        vec = tokenise(line);
    }

    std::cout << "The following " << vec.size() << " numbers were read:\n";
    std::copy(vec.begin(), vec.end(), std::ostream_iterator<int>(std::cout, "\n"));
}
于 2013-02-14T03:40:02.177 に答える
0

if次の位置は区切り文字になるため、 に陥ることはありません。

                string delimiters = " ";
                ...
                        next = line.find_first_of( delimiters, current );
                        if((line[next] <=57)&&(line[next] >=48))
                        ...

delimitersで構成されているため、スペース文字になります" "line[next]

問題の説明から、オペレーターを救うコードが欠落しています。演算子を見つけようとするコードはありません。

数字のテストに ASCII を想定する必要はありません。is_digit()たとえば、を使用したり、 と を比較し'9'たりできます'0'

ベクター要素を印刷すると、配列にアイテムが挿入されていない可能性があるため、ベクターに不適切にアクセスしている可能性があります。

于 2013-02-14T01:11:38.887 に答える