tampon du flux entrant

Le
Lahsen
Comment vider le tampon du flux entrant: cin?

je l'utilise deux fois de suite comme suit

vector<int> vInt;
copy(istream_iterator<int>(cin),
istream_iterator<int>(),
back_inserter(vInt));
copy(vInt.begin(), vInt.end(), ostream_iterator<int>(cout,
""));
cout << endl;


istream_iterator<string> first(cin), last;
deque<string> col(first, last);
copy(col.begin(), col.end(), ostream_iterator<string>(cout, " "));
cout << endl;

et ladeuxième sortie standard m'affiche en premier le caractère de fin
de la première entrée standard ( cin)!!!

j'ai utilisé des:
cout.flush();
cin.clear();
cin.tie(0);

mais rien n'a vidé la memoire tampon du flux du premier cin ( la
première entrée standar)!!!
Questions / Réponses high-tech
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
James Kanze
Le #309806
On Jul 25, 1:21 am, Lahsen
Comment vider le tampon du flux entrant: cin?


En le lisant.

En principe, la gestion des tampons est transparent ; que tu
lis un caractère du tampon, ou que la bibiothèque aille au
système (qui a ses propre tampons), à part le temps que ça
prend, tu ne vois pas de différence.

je l'utilise deux fois de suite comme suit

vector<int> vInt;
copy(istream_iterator<int>(cin),
istream_iterator<int>(),
back_inserter(vInt));
copy(vInt.begin(), vInt.end(), ostream_iterator<int>(cout,
"n"));
cout << endl;


Tu as donc lu std::cin jusqu'à la fin. Le tampon doit en être
vide ; sinon, tu seras toujours en cours de la première copie.

istream_iterator<string> first(cin), last;
deque<string> col(first, last);
copy(col.begin(), col.end(), ostream_iterator<string>(cout, " "));
cout << endl;

et ladeuxième sortie standard m'affiche en premier le caractère de fin
de la première entrée standard ( cin)!!!


Le deuxième sortie ne doit t'afficher rien du tout, parce que
col sera forcement vide. Les flux mémoirse leurs « erreurs »,
et une fois qu'un flux a rencontré la fin de fichier, il
n'essaie plus rien.

Si std::cin est connecté à un fichier, tu pourrais faire quelque
chose du genre :

std::cin.clear() ; // Effacer l'erreur.
std::cin.seekg( 0, std::ios::beg ) ;
// Repositionner au début.

Si en revanche std::cin est connecté à un clavier, tu n'as qu'à
effacer l'erreur, puis démander à l'utilisateur de rentrer les
données une deuxième fois.

j'ai utilisé des:
cout.flush();
cin.clear();
cin.tie(0);

mais rien n'a vidé la memoire tampon du flux du premier cin ( la
première entrée standar)!!!


Comme j'ai dit, la mémoire tampon de std::cin est forcement
vide ; sinon, la copy initiale ne se termine pas. C'est l'état
d'avoir rencontré la fin du fichier qu'il faut effacer. Mais
même en l'effaçant, tu restes à la position où tu étais. Si ce
qui est connecté au std::cin supporte le positionnement au moyen
de seek, tu pourrais revenir en arrière, et le rélire. Sinon (et
ni un clavier, ni une pipe ne supporte le seek), il n'y a rien à
faire.

Puisque manifestement, les données se tiennent toutes en
mémoire, la solution la plus simple ne serait-elle pas de
lire tout le ficher dans une chaîne, puis se servir des
std::istringstream pour le rélire autant de fois qu'on veut.
Quelque chose du genre :

std::ostringstream getter ;
getter << std::cin.rdbuf() ;
std::string data = getter.str() ;

std::istringstream in1( data ) ;
std::copy( std::istream_iterator< int >( in1 ),
std::istream_iterator< int >(),
std::back_inserter( vInt ) ) ;
std::copy( vInt.begin(), vInt.end(),
std::ostream_iterator< int >( std::cout, "n" ) ) ;
std::cout << std::endl ;

std::istringstream in2( data ) ;
std::istream_iterator< string> first( in2 ) ;
std::istream_iterator< string> last ;
deque< string> col( first, last ) ;
std::copy( col.begin( ), col.end( ),
std::ostream_iterator< string> ( std::cout, " " ) ) ;
std::cout << std::endl ;

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Publicité
Poster une réponse
Anonyme