Преобразовать строку, содержащую несколько чисел, в целые числа - PullRequest
31 голосов
/ 24 августа 2009

Я понимаю, что этот вопрос, возможно, задавался несколько раз в прошлом, но я собираюсь продолжить в любом случае.

У меня есть программа, которая собирается получить строку чисел с клавиатуры. Числа всегда будут в форме «66 33 9». По сути, каждое число разделяется пробелом, а пользовательский ввод всегда будет содержать различное количество чисел.

Я знаю, что использование 'sscanf' сработало бы, если бы количество чисел в каждой введенной пользователем строке было постоянным, но это не так для меня. Кроме того, поскольку я новичок в C ++, я бы предпочел иметь дело со «строковыми» переменными, а не с массивами символов.

Ответы [ 8 ]

35 голосов
/ 24 августа 2009

Я предполагаю, что вы хотите прочитать всю строку и проанализировать ее как ввод. Итак, сначала возьмем строку:

std::string input;
std::getline(std::cin, input);

Теперь поместите это в stringstream:

std::stringstream stream(input);

и разбор

while(1) {
   int n;
   stream >> n;
   if(!stream)
      break;
   std::cout << "Found integer: " << n << "\n";
}

Не забудьте включить

#include <string>
#include <sstream>
19 голосов
/ 26 августа 2009

Библиотека C ++ String Toolkit (Strtk) имеет следующее решение вашей проблемы:

#include <iostream>
#include <string>
#include <deque>
#include <algorithm>
#include <iterator>

#include "strtk.hpp"

int main()
{
   std::string s = "1 23 456 7890";

   std::deque<int> int_list;
   strtk::parse(s," ",int_list);

   std::copy(int_list.begin(),
             int_list.end(),
             std::ostream_iterator<int>(std::cout,"\t"));

   return 0;
}

Больше примеров можно найти Здесь

9 голосов
/ 24 августа 2009
#include <string>
#include <vector>
#include <iterator>
#include <sstream>
#include <iostream>

int main() {
   std::string input;
   while ( std::getline( std::cin, input ) )
   {
      std::vector<int> inputs;
      std::istringstream in( input );
      std::copy( std::istream_iterator<int>( in ), std::istream_iterator<int>(),
         std::back_inserter( inputs ) );

      // Log process: 
      std::cout << "Read " << inputs.size() << " integers from string '" 
         << input << "'" << std::endl;
      std::cout << "\tvalues: ";
      std::copy( inputs.begin(), inputs.end(), 
         std::ostream_iterator<int>( std::cout, " " ) );
      std::cout << std::endl;
   }
 }
3 голосов
/ 24 августа 2009
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
using namespace std;

int ReadNumbers( const string & s, vector <int> & v ) {
    istringstream is( s );
    int n;
    while( is >> n ) {
        v.push_back( n );
    }
    return v.size();
}

int main() {
    string s;
    vector <int> v;
    getline( cin, s );
    ReadNumbers( s, v );
    for ( int i = 0; i < v.size(); i++ ) {
        cout << "number is " <<  v[i] << endl;
    }
}
1 голос
/ 24 августа 2009

Универсальное решение для беззнаковых значений (работа с префиксом '-' требует дополнительной логики):

template<typename InIter, typename OutIter>
void ConvertNumbers(InIter begin, InIter end, OutIter out)
{
    typename OutIter::value_type accum = 0;
    for(; begin != end; ++begin)
    {
        typename InIter::value_type c = *begin;
        if (c==' ') {
            *out++ = accum; accum = 0; break;
        } else if (c>='0' && c <='9') {
            accum *= 10; accum += c-'0';
        }
    }
    *out++ = accum;
       // Dealing with the last number is slightly complicated because it
       // could be considered wrong for "1 2 " (produces 1 2 0) but that's similar
       // to "1  2" which produces 1 0 2. For either case, determine if that worries
       // you. If so: Add an extra bool for state, which is set by the first digit,
       // reset by space, and tested before doing *out++=accum.
}
1 голос
/ 24 августа 2009
// get string
std::string input_str;
std::getline( std::cin, input_str );

// convert to a stream
std::stringstream in( input_str );

// convert to vector of ints
std::vector<int> ints;
copy( std::istream_iterator<int, char>(in), std::istream_iterator<int, char>(), back_inserter( ints ) );
1 голос
/ 24 августа 2009

Вот , как разбить вашу строку на строки вдоль пробелов. Затем вы можете обработать их один за другим.

0 голосов
/ 24 августа 2009

Попробуйте strtoken сначала отделить строку, затем вы разберетесь с каждой строкой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...