【问题标题】:Parse string containing numbers into integer array将包含数字的字符串解析为整数数组
【发布时间】:2013-07-18 13:32:23
【问题描述】:

一个字符串作为输入,由数字组成,我想在 C++ 中将其转换为整数数组。

#include <string>
#include <iostream>
#include <sstream>

using std::string;
using std::stringstream;
using std::cout;
using std::endl;

int main(int argc,char** argv) {

    string num="-24 2 90 24 50 76";

    stringstream stream(num);

    while(stream){
        int n;
        stream>>n;
        cout<<n<<endl;
    }

    return 0;
}

输出(GCC):

-24 2 90 24 50 76 76

为什么我会获得额外的价值,将它们转换为整数数组的效率是什么?

更新:

如果字符串流包含除空格以外的分隔符,如何解析? 例如: string num="-24,2,90,24,50,76";

【问题讨论】:

  • 不,将它们存储在向量中是将它们放入数组中的好方法。

标签: c++ arrays string parsing


【解决方案1】:

文件结束条件是成功解析时设置的,你必须在解析后检查流的状态。

第二个76 基本上只是纯粹的机会。不成功的解析使目标操作数保持不变,并且因为您没有初始化 n,所以它可以是任何东西。

快速修复:

stream>>n;
if (stream)
    cout<<n<<endl;

更干净的修复:

int n;
while(stream >> n){
    cout<<n<<endl;
}

要存储这些整数,规范的方法是在元素数量未知的情况下使用std::vector。示例用法:

std::vector<int> values;
int n;
while(stream >> n){
    ...do something with n...
    values.push_back(n);
}

但是,您可以在流上使用迭代器并使用以下内容:

// Use std::vector's range constructor
std::vector<int> values(
     (std::istream_iterator<int>(stream)), // begin
     (std::istream_iterator<int>()));      // end

【讨论】:

  • 其实值不是未定义的;对于数字输入转换,标准保证在出现错误时不会修改目标。所以他可以保证看到最后读取的值。
  • 重要的一点是他在没有检查输入是否成功的情况下使用该值。 (这在您的代码中是隐含的,但值得明确说明。)
  • 最后,如果你想要一个 int 的向量,规范的方法是:std::vector&lt;int&gt; values( (std::istream_iterator&lt;int&gt;( stream )), (std::istream_iterator&lt;int&gt;()) );。没有循环,没有push_back;一切都发生在构造函数中。
  • @JamesKanze: 但它是未定义的,因为n 没有被初始化;我对此进行了详细说明。很好的第二个第三点,很高兴您查看了我的答案。
  • 啊,是的。因为他每次都定义一个新的n。我在想一些类似于int n; while ( !stream.eof() )(我们经常看到)的东西。
【解决方案2】:

使用向量处理字符分隔的整数列表的另一种方法可能更简单一些,如下所示:

string str = "50,2,25,38,9,16";
vector<int> ints;
stringstream ss(str);
int n;
char ch;

while(ss >> n) {
    if(ss >> ch)
        ints.push_back(n);
    else
        ints.push_back(n);
}

这样您就可以先跳过任何字符分隔符(如果存在),然后默认返回抓取整数并将它们添加到列表中(如果它们不存在)(也就是列表的末尾)

【讨论】:

    【解决方案3】:

    我不知道您是否找到更新问题的答案。如果你不这样做,你可以通过代码轻松完成

    for (string::iterator it = num.begin(); it != num.end(); ++it) {
        if (*it == ',') {
            *it = ' ';
        }
        else continue;
    }
    

    此代码删除所有冒号并用空格替换它们。那么你就可以正常进行了

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 1970-01-01
      • 2013-12-08
      • 2010-12-18
      • 1970-01-01
      相关资源
      最近更新 更多