1

我正在尝试使用 C++ 将字符串分解为“符号”以进行进一步的工作。我已经很久没有用 C++ 写过任何东西了,所以如果这段代码本身有什么问题,请原谅我。

下面函数的目的symbolize()是将一个字符串,例如“5+5”,分解成一个vector字符串,例如{"5","+","5"}。它不工作。如果您认为代码太乱,请提出一种简化它的方法。

到目前为止,这是我的代码:

#include <iostream>
#include <string>
#include <vector>
#include <ctype.h>
#include <sstream>

using namespace std;

vector<string> symbolize(string);

int main(int argc, const char * argv[])
{

    string input;
    cin >> input;

    vector<string> symbols;

    symbols = symbolize(input);

    for(int i=0;i<symbols.size();i++){
        cout<<symbols.at(i) << endl;
    }

    return 0;
}


vector<string> symbolize(string input){
    int position = 0;
    char c;
    stringstream s;
    vector<string> symbols;
    enum symbolType {TEXT,OPERATOR}symbolType,charType;

    while(position < input.size()){
        c = input.at(position);
        if(isalnum(c))symbolType = TEXT;
        else symbolType = OPERATOR;
        charType = symbolType;

        while(symbolType == charType){
            s << c;
            position++;
            if(position>=input.length())break;
            c = input.at(position);
            if(isalnum(c)) charType = TEXT;
            else charType = OPERATOR;
        }

        symbols.push_back(s.str());
        s.clear();
    }

    return symbols;
}

谢谢参观。

编辑:顺便说一句,我应该提到该函数返回第一个“令牌”,例如“5+5”->“5”

编辑2:我错了。我刚刚尝试了“5+5”,它返回了{"5","5+","5+5"}。但是,它只返回空格前的第一个。对困惑感到抱歉!

编辑3:谢谢大家!对于那些将来可能会遇到此页面的人,这里是说完所有事情后的代码:

#include <iostream>
#include <string>
#include <vector>
#include <ctype.h>
#include <sstream>

using namespace std;

vector<string> symbolize(string);

int main(int argc, const char * argv[])
{

    string input;
    getline(cin,input);

    vector<string> symbols;

    symbols = symbolize(input);

    for(int i=0;i<symbols.size();i++){
        cout<<symbols.at(i) << endl;
    }

    return 0;
}


vector<string> symbolize(string input){
    int position = 0;
    char c;
    //stringstream s;
    vector<string> symbols;
    enum symbolType {TEXT,OPERATOR}symbolType,charType;

    while(position < input.size()){
        stringstream s;
        c = input.at(position);
        if(isalnum(c))symbolType = TEXT;
        else symbolType = OPERATOR;
        charType = symbolType;

        while(symbolType == charType){
            s << c;
            position++;
            if(position>=input.length())break;
            c = input.at(position);
            if (isspace(c)||c=='\n'){position++; break;}
            if(isalnum(c)) charType = TEXT;
            else charType = OPERATOR;
        }

        symbols.push_back(s.str());
    }

    return symbols;
}
4

3 回答 3

3

stringstream::clear 不清除字符串缓冲区(仅清除错误状态)。

您可以使用stringstream::str(x)设置字符串缓冲区,因此s.str(string())s.str("")代替s.clear()将清除字符串缓冲区。

此外,operator<<(istream, ...)直到空白才读取。

对于阅读,您可以尝试使用:

  • istream::get 一次读取一个字符;或者;
  • std::getline(istream,...) 一次读取一行;或者;
  • istream::read 将任意数量的字符读入缓冲区。

http://en.cppreference.com/w/cpp/io/basic_istream

于 2012-04-27T22:27:13.527 回答
3

如果您想阅读一整行而不是一个单词,请使用 getline 而不是 operator>>。有关详细信息,请参见http://www.cplusplus.com/reference/string/getline/,或者只需将第 14 行更改为“getline(cin, input);”。

另外,如果要输出“5”、“+”、“5”而不是“5”、“5+”、“5+5”,每次循环都需要重新设置stringstream,而clear不会不要那样做。解决这个问题的最简单方法是在外循环中声明 stringstream 并摆脱 clear 调用。

于 2012-04-27T22:35:47.180 回答
1

如果你stringstream s;在第一个while循环内移动,你应该达到你的目标。

s.clear()重置字符串流的错误状态标志,它不像std::string::clear()

于 2012-04-27T22:32:20.493 回答