从包含其他字符

时间:2015-05-05 00:09:52

标签: c++11 visual-c++ string-parsing

我在c ++中从string中提取signed int时遇到问题。 假设我有一个images1234字符串,如何在不知道C ++中最后一个非数字字符的位置的情况下从字符串中提取1234

仅供参考,我已尝试使用stringstream和lexical_cast,正如其他人通过帖子所建议的那样,但是当lexical_cast停止工作时,stringstream返回0。

int main()
{
    string virtuallive("Images1234");
    //stringstream output(virtuallive.c_str());
    //int i = stoi(virtuallive);
    //stringstream output(virtuallive);
    int i;
    i = boost::lexical_cast<int>(virtuallive.c_str());
    //output >> i;
    cout << i << endl;
    return 0;
}

2 个答案:

答案 0 :(得分:2)

  

如何在不知道C ++中最后一个非数字字符的位置的情况下从字符串中提取1234?

你不能。但这个立场并不难找到:

auto last_non_numeric = input.find_last_not_of("1234567890");
char* endp = &input[0];
if (last_non_numeric != std::string::npos)
    endp += last_non_numeric + 1;
if (*endp) { /* FAILURE, no number on the end */ }
auto i = strtol(endp, &endp, 10);
if (*endp) {/* weird FAILURE, maybe the number was really HUGE and couldn't convert */}

答案 1 :(得分:1)

另一种可能性是将字符串放入stringstream,然后从流中读取数字(在使用将数字除外的所有内容分类为空格的区域设置之后)。

// First the desired facet:
struct digits_only: std::ctype<char> {
    digits_only(): std::ctype<char>(get_table()) {}

    static std::ctype_base::mask const* get_table() {
        // everything is white-space:
        static std::vector<std::ctype_base::mask> 
            rc(std::ctype<char>::table_size,std::ctype_base::space);

        // except digits, which are digits
        std::fill(&rc['0'], &rc['9'], std::ctype_base::digit);

        // and '.', which we'll call punctuation:
        rc['.'] = std::ctype_base::punct;
        return &rc[0];
    }
};

然后读取数据的代码:

std::istringstream virtuallive("Images1234");
virtuallive.imbue(locale(locale(), new digits_only);

int number;

// Since we classify the letters as white space, the stream will ignore them.
// We can just read the number as if nothing else were there:
virtuallive >> number;

这种技术主要在流包含大量数据时非常有用,并且您希望 all 以相同的方式解释该流中的数据(例如,只读取数字,无论它可能包含的其他内容。)