【问题标题】:Taking integers out of a string C++ [duplicate]从字符串C++中取出整数[重复]
【发布时间】:2014-06-02 04:04:00
【问题描述】:

我想知道如何在 C++ 中从字符串中提取数字。我从输入中获取字符串并将获得多行,但我已经可以读取行。 注意:行总是有偶数个整数

我希望代码如下所示:

std::getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
int a, b;
while(!line.empty() /*line still has ints to extract*/) {
    a = someMethod(line);//gets first int.  So, 10 first loop, 40 second, 8 third
    b = someMethod(line);//gets second int. So, 3 first loop, 45 second, 12 third
    myMethod(a,b);//a method from elsewhere in my code.  It's here so you know that I need both a and b
}

任何类似的东西都会有所帮助。非常感谢!

【问题讨论】:

  • std::stringstream 怎么样?
  • 我该如何使用 stringstream 呢?我只是对它有点熟悉。
  • @user2670028:您将从line 构造它,然后以与从std::cin 提取整数相同的方式使用它。图书馆以这种方式很好地正交。但是,有些事情需要注意 - 请参阅 How to parse a string to an int in C++
  • @Simon 我想我已经想出了一个可以使用这个想法的方法,谢谢!
  • 在这里提问之前你有没有做任何研究。这个答案太多了,随便搜一下:parse space delimited numbers c++ and google 都有很多解决方法。

标签: c++ string integer


【解决方案1】:

这是一个完整的例子。

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


int main(){
    std::string line = "2 4 56 6";
    std::stringstream stream(line);
    int i;
    while (stream >> i) {
        std::cout << i << std::endl;
    }
}

下面的工作也很好,所以阅读多行应该不是问题。

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


int main(){
    std::string line = "2 4 56 6";
    std::stringstream stream(line);
    int i;
    while (stream >> i) {
        std::cout << i << std::endl;
    }

    line =  "32 62 44 6 22 58 34 60 71 86";
    stream.clear();
    stream.str(line);
    int a,b;
    while(stream >> a && stream >> b){ 
        std::cout << a << " " << b << "\n";
    }
}

【讨论】:

  • while(!stream.eof()) 已损坏 - eof 直到读取操作失败后才设置 - 它不保证下一次读取不会失败(它怎么会 - 它不知道您将尝试阅读的内容)。你应该直接使用while (stream &gt;&gt; i)
  • @TonyD,公平点,已修复。
  • @merlin2011 谢谢,这很像我根据另一条评论创建的。唯一缺少的(我想问题中没有完全指定,抱歉)是我需要字符串流也可以用于下一行。我必须创建一个新的字符串流还是你知道如何获取下一个版本的“line”?
  • @user2670028,您应该可以通过执行stream.clear() 后跟stream.str(line) 来重用它。
  • @merlin2011 最后我是核心转储。我的代码:while(stream &gt;&gt; a &amp;&amp; stream &gt;&gt; b){ cout &lt;&lt; a &lt;&lt; " " &lt;&lt; b &lt;&lt; "\n"; myMethod(a,b); } 输出行“32 62 44 6 22 58 34 60 71 86”:32 62 44 66 22 58 34 60 分段错误顺便说一句,感谢您的帮助。我现在可能可以自己解决这个问题,但我仍然遇到这个错误。
【解决方案2】:

从字符串行中获取令牌并根据需要使用它们。

#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>

using namespace std;

typedef boost::tokenizer<boost::char_separator<char> >
    tokenizer;


void myMethod(int a, int b)
{
    cout<<a<<" "<<b<<endl;
}

void getNumber(string line)
{            
    boost::char_separator<char> sep(" ");
    tokenizer tokens(line, sep);    
    string evenStr, oddStr;

    for(tokenizer::iterator iterToken=tokens.begin();
          iterToken != tokens.end(); ++iterToken)
    {
        evenStr = *iterToken;                       
        ++iterToken;
        if(iterToken != tokens.end())
        {
            oddStr = *iterToken;                                   
        myMethod(atoi(evenStr.c_str()), atoi(oddStr.c_str()));
        }        
    }    
}

int main()
{
   string line("10 3 40 45 8 12");
   getNumber(line);

   return 0;
}

【讨论】:

    【解决方案3】:

    你可以这样做:

    string line;
    getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
    int a,  b;
    
    vector<string> tokens;
    istringstream iss(line);
    
    copy(istream_iterator<string>(iss), 
         istream_iterator<string>(),
         back_inserter<vector<string> >(tokens));
    
    stringstream s;
    for (int i=0;i<tokens.size()/2;i++)
    {   
      s<< tokens[i];
      s>>a;
      s.clear();
      s<<tokens[i+2];
      s>>b;
      s.clear();
      myMethod(a,b);
    }
    

    【讨论】:

    【解决方案4】:

    有多种方法可以实现这一目标。我更喜欢使用 boost。

    例子:

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    
    #include <boost/algorithm/string.hpp>
    #include <boost/lexical_cast.hpp>
    
    int main()
    {
        std::string line = "10 3 40 45 8 12 9"; //std::getline(std::cin, line);// line looks something like "10 3 40 45 8 12"
    
        std::vector<std::string> intNumbers;
        std::string s;
        boost::split(intNumbers, line, boost::is_any_of(" "), boost::token_compress_on);
    
        unsigned int i=0;
        while(i < intNumbers.size())
        {
            try{
                int a = boost::lexical_cast<int>(intNumbers[i++]);
    
                if(i >= intNumbers.size())
                {
                    std::cout << "invlaid values" << std::endl;
                    break;
                }
                int b = boost::lexical_cast<int>(intNumbers[i++]);
    
                std::cout << "value a: " << a << std::endl;
                std::cout << "value b: " << b << std::endl;
    
                std::cout << "my method (multiply) a*b: " << (a*b) << std::endl;
            }
            catch(boost::bad_lexical_cast &e)
            {
                std::cout << "invlaid values" << std::endl;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2015-11-30
      • 2014-11-11
      • 2021-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 2016-06-09
      相关资源
      最近更新 更多