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.
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>
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
#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;
}
}
// 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 ) );
Voici comment diviser votre chaîne en chaînes le long des espaces. Ensuite, vous pouvez les traiter un par un.
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.
}
Essayez strtoken
pour séparer la chaîne en premier, puis vous traiterez chaque chaîne.