0

我有一个字符串str ( "1 + 2 = 3" )。我想以十进制值(不是 ASCII )获取字符串的各个数字。我试过atoic_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();

在这种情况下vec[0]打印50not 2

4

3 回答 3

4

您需要学习分隔字符串。您的分隔字符将是数学运算符(即:

C:从分隔的源字符串创建字符串数组

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

对于第二个链接,您可以执行以下操作:

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

有了这些知识,您可以创建一个字符串数组,并在每个字符串上调用 atoi() 以获取等效的数字。然后您可以使用每个分隔符的地址(数组索引)来确定存在哪个运算符。

对于像加法和减法这样的事情,这将非常简单。如果你想要运算顺序和乘法、括号等,你的流程逻辑会更复杂。

有关更深入的示例,请参阅此最终链接。一个简单的 C 命令行计算器。这应该让它一清二楚。

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

于 2013-02-13T23:59:03.923 回答
0

不要fin.eof()用来控制循环。该功能仅在读取失败后才有用。

有多种方法可以int从 a 中获取 sstd::string ,在这种情况下,我std::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组成" ", thenline[next]将是一个空格字符。

根据您的问题描述,您缺少可以节省操作员的代码。没有代码可以尝试查找运算符。

您不必假设 ASCII 来测试数字。您可以使用is_digit()例如,也可以与'9'and进行比较'0'

当你打印你的向量元素时,你可能会不恰当地访问向量,因为可能没有任何项目被插入到数组中。

于 2013-02-14T01:11:38.887 回答