@Steve Townsend a déjà souligné une possibilité. Si vous préférez utiliser operator>>
au lieu de std::getline
, vous pouvez le faire aussi. Un istream
traite toujours les espaces comme séparateur. Chaque flux a des paramètres régionaux associés et chaque paramètre régional inclut une facette ctype
. Cette facette ctype
est ce que le istream
utilise pour déterminer quels caractères d'entrée sont des espaces. Dans votre cas, vous voulez apparemment que le flux traite uniquement les lignes et les deux-points comme des "espaces blancs" (par exemple, des séparateurs), tandis que le caractère espace réel est simplement traité comme un caractère "normal" et non comme un séparateur.
Pour ce faire, vous pouvez créer une facette comme ctype ceci:
struct field_reader: std::ctype<char> {
field_reader(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<std::ctype_base::mask>
rc(table_size, std::ctype_base::mask());
rc['\n'] = std::ctype_base::space;
rc[':'] = std::ctype_base::space;
return &rc[0];
}
};
Pour utiliser cela, vous devez « imprégner » le flux avec un lieu en utilisant cette facette:
int main() {
std::stringstream input("A:KT5:14:executive desk:");
// have the stream use our ctype facet:
input.imbue(std::locale(std::locale(), new field_reader()));
// copy fields from the stream to standard output, one per line:
std::copy(std::istream_iterator<std::string>(input),
std::istream_iterator<std::string>(),
std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
Je suis le premier à admettre, cependant, que cela a quelques défauts. Tout d'abord, les locales et les facettes sont généralement assez mal documentées, donc les programmeurs C++ sont susceptibles de trouver cela assez difficile à comprendre (surtout quand tout le vrai travail se passe "sous les couvertures", pour ainsi dire).
Une autre possibilité est d'utiliser Boost Tokenizer. En toute honnêteté, c'est un peu plus de travail à utiliser - il faudra que vous fassiez quelque chose comme lire une chaîne, puis la séparer séparément.En même temps, il est bien documenté, assez largement connu, et cadre assez bien avec les idées préconçues des gens sur la façon de faire des choses comme ça, que beaucoup de gens trouveront probablement plus facile à suivre malgré la complexité supplémentaire.
Wow ... et pas dans le bon sens. Je pense que je vais m'en tenir à C. – onemasse
merci Steve !!! – rajh2504
@onemasse, erm: la déclaration ressemble à: 'istream & getline (istream & is, chaîne & str, char delim);', n'est-ce pas si mal maintenant? :), sans parler de ce que 'std :: getline' vous donne sur l'équivalent C! :) – Nim