Dupliquer possible:
Comment diviser une chaîne en C++?
Je dois diviser une chaîne par des espaces simples et la stocker dans un tableau de chaînes. Je peux y arriver en utilisant un istringstream, mais ce que je ne suis pas capable de faire, c'est ceci:
Je veux que chaque espace termine le mot actuel. Donc, s'il y a deux espaces consécutifs, un élément de mon tableau doit être vide.
Par exemple:
(le trait de soulignement indique l'espace)
This_is_a_string.
gets split into:
A[0] = This
A[1] = is
A[2] = a
A[3] = string.
This__is_a_string.
gets split into:
A[0] = This
A[1] = ""
A[2] = is
A[3] = a
A[4] = string.
Comment puis-je implémenter cela?
Vous pouvez même développer votre propre fonction de partage (je sais, un peu démodé):
size_t split(const std::string &txt, std::vector<std::string> &strs, char ch)
{
size_t pos = txt.find( ch );
size_t initialPos = 0;
strs.clear();
// Decompose statement
while( pos != std::string::npos ) {
strs.Push_back( txt.substr( initialPos, pos - initialPos ) );
initialPos = pos + 1;
pos = txt.find( ch, initialPos );
}
// Add the last one
strs.Push_back( txt.substr( initialPos, std::min( pos, txt.size() ) - initialPos + 1 ) );
return strs.size();
}
Ensuite, il vous suffit de l'invoquer avec un vecteur <string> en tant qu'argument:
int main()
{
std::vector<std::string> v;
split( "This is a test", v, ' ' );
dump( cout, v );
return 0;
}
Recherchez le code permettant de fractionner une chaîne dans IDEone .
J'espère que cela t'aides.
Si le délimiteur est strictement composé d'un seul caractère, Probablement std::getline
sera valide.
Par exemple:
int main() {
using namespace std;
istringstream iss("This is a string");
string s;
while ( getline( iss, s, ' ' ) ) {
printf( "`%s'\n", s.c_str() );
}
}
Pouvez-vous utiliser boost ?
samm$ cat split.cc
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/foreach.hpp>
#include <iostream>
#include <string>
#include <vector>
int
main()
{
std::string split_me( "hello world how are you" );
typedef std::vector<std::string> Tokens;
Tokens tokens;
boost::split( tokens, split_me, boost::is_any_of(" ") );
std::cout << tokens.size() << " tokens" << std::endl;
BOOST_FOREACH( const std::string& i, tokens ) {
std::cout << "'" << i << "'" << std::endl;
}
}
exemple de réalisation:
samm$ ./a.out
8 tokens
'hello'
'world'
''
'how'
'are'
''
''
'you'
samm$
Si vous êtes réticent à l’optimisation, vous pouvez utiliser l’ancien operator>>
classique, avec std::noskipws
:
EDIT: mises à jour après test.
#include <iostream>
#include <iomanip>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>
#include <sstream>
void split(const std::string& str, std::vector<std::string>& v) {
std::stringstream ss(str);
ss >> std::noskipws;
std::string field;
char ws_delim;
while(1) {
if( ss >> field )
v.Push_back(field);
else if (ss.eof())
break;
else
v.Push_back(std::string());
ss.clear();
ss >> ws_delim;
}
}
int main() {
std::vector<std::string> v;
split("hello world how are you", v);
std::copy(v.begin(), v.end(), std::ostream_iterator<std::string>(std::cout, "-"));
std::cout << "\n";
}
Si vous n'êtes pas opposé au boost, boost.tokenizer est suffisamment flexible pour le résoudre.
#include <string>
#include <iostream>
#include <boost/tokenizer.hpp>
void split_and_show(const std::string s)
{
boost::char_separator<char> sep(" ", "", boost::keep_empty_tokens);
boost::tokenizer<boost::char_separator<char> > tok(s, sep);
for(auto i = tok.begin(); i!=tok.end(); ++i)
std::cout << '"' << *i << "\"\n";
}
int main()
{
split_and_show("This is a string");
split_and_show("This is a string");
}
test: https://ideone.com/mN2sR
Vous pouvez aussi simplement utiliser l'ancienne mode 'strtok'
http://www.cplusplus.com/reference/clibrary/cstring/strtok/
C'est un peu bizarre mais n'implique pas l'utilisation de boost (ce n'est pas une mauvaise chose).
En gros, vous appelez strtok avec la chaîne que vous voulez scinder et le délimiteur (dans ce cas, un espace) et il vous renverra un char *.
Du lien:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Vous pouvez utiliser la fonction simple strtok () (*) à partir d'ici . Notez que les jetons sont créés sur des délimiteurs
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This is a string";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}