web-dev-qa-db-fra.com

Convertir une chaîne contenant plusieurs nombres en entiers

Je me rends compte que cette question a peut-être été posée plusieurs fois dans le passé, mais je vais continuer malgré tout.

J'ai un programme qui va obtenir une chaîne de chiffres à partir du clavier. Les nombres seront toujours sous la forme "66 33 9". Essentiellement, chaque nombre est séparé par un espace et l'entrée utilisateur contiendra toujours une quantité différente de nombres.

Je suis conscient que l'utilisation de 'sscanf' fonctionnerait si le nombre de nombres dans chaque chaîne entrée par l'utilisateur était constant, mais ce n'est pas le cas pour moi. De plus, comme je suis nouveau en C++, je préférerais m'occuper des variables "chaîne" plutôt que des tableaux de caractères.

31
GobiasKoffi

Je suppose que vous voulez lire une ligne entière et l'analyser en entrée. Alors, saisissez d'abord la ligne:

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

Maintenant, mettez cela dans un stringstream:

std::stringstream stream(input);

et analyser

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

N'oubliez pas d'inclure

#include <string>
#include <sstream>
36
Jesse Beder

C++ String Toolkit Library (Strtk) a la solution suivante à votre problème:

#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;
}

Plus d'exemples peuvent être trouvés ici

19
Matthieu N.
#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;
   }
 }
#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;
    }
}
3
anon
// 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 ) );
2

Voici comment diviser votre chaîne en chaînes le long des espaces. Ensuite, vous pouvez les traiter un par un.

1
Zed

Solution générique pour les valeurs non signées (le préfixe "-" prend un bool supplémentaire):

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
MSalters

Essayez strtoken pour séparer la chaîne en premier, puis vous traiterez chaque chaîne.

0
Benny