IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
logo

FAQ C++Consultez toutes les FAQ

Nombre d'auteurs : 34, nombre de questions : 368, derni�re mise � jour : 14 novembre 2021  Ajouter une question

 

Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur les forums de http://www.developpez.com et de l'exp�rience personnelle des auteurs.

Je tiens � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur ou si vous souhaitez devenir r�dacteur, lisez ceci.

Sur ce, nous vous souhaitons une bonne lecture.

SommaireEntr�es / sorties avec les flux (35)
pr�c�dent sommaire suivant
 

En plus de faire un retour � la ligne en ajoutant un caract�re '\n', std::endl purge le buffer de sortie et force ainsi son �criture en appelant ostream::flush() (cela a le m�me fonctionnement que la fonction fflush() du C).
Les deux lignes de code suivantes sont donc �quivalentes :

Code c++ : S�lectionner tout
1
2
std::cout << "coucou" << std::endl; 
std::cout << "coucou\n" << std::flush;

Il faut donc �tre prudent avec son utilisation, notamment avec les fichiers, car une op�ration de flush n'est pas gratuite. Son utilisation fr�quente peut m�me s�rieusement grever les performances en annulant tous les b�n�fices d'une �criture bufferis�e.

Mis � jour le 18 avril 2005 Aurelien.Regat-Barrel LFE

Pour injecter un objet de type quelconque dans un flux de sortie, il suffit de d�finir un op�rateur << prenant en param�tre le flux, ainsi que l'objet � injecter.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <ostream> 
#include <string> 
  
class MaClasse 
{ 
    friend std::ostream& operator <<(std::ostream&, const MaClasse&); 
  
private : 
  
    int Integer; 
    std::string String; 
}; 
  
std::ostream& operator <<(std::ostream& Stream, const MaClasse& Obj) 
{ 
    Stream << Obj.Integer << " " << Obj.String; 
    return Stream; // N'oubliez pas de renvoyer le flux, afin de pouvoir cha�ner les appels 
} 
  
MaClasse Obj; 
std::cout << "Ma classe : " << Obj << std::endl;
Notez qu'ici notre surcharge d'op�rateur est d�clar�e amie de la classe, car elle a besoin d'acc�der aux donn�es priv�es de celle-ci. Cependant ce n'est pas obligatoire, notamment si les accesseurs ad�quats ont �t� pr�vus dans la classe.

Le fonctionnement est le m�me pour l'extraction de valeurs � partir d'un flux d'entr�e, via l'op�rateur >> :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <istream> 
#include <string> 
  
class MaClasse 
{ 
    friend std::istream& operator >>(std::istream&, MaClasse&); 
  
private : 
  
    int Integer; 
    std::string String; 
}; 
  
std::istream& operator >>(std::istream& Stream, MaClasse& Obj) 
{ 
    Stream >> Obj.Integer >> Obj.String; 
    return Stream; // N'oubliez pas de renvoyer le flux, afin de pouvoir cha�ner les appels 
} 
  
MaClasse Obj; 
std::cin >> Obj;
Le fait de prendre en param�tre un ostream ou un istream permettra d'utiliser nos surcharges avec n'importe quel type de flux (stringstream, fstream.) puisque ceux-ci d�rivent tous des classes ostream (pour les flux d'entr�e) et istream (pour les flux de sortie).

Notez bien que ce genre de surcharge ne peut pas �tre membre de la classe, car cela impliquerait que l'op�rande gauche soit l'objet et non le flux.

Enfin, si vous devez g�rer l'injection et l'extraction sur une hi�rarchie d'objets polymorphes, il faudra mettre en place une petite astuce (voir Comment surcharger correctement l'op�rateur << pour afficher des objets polymorphes ?).

Mis � jour le 3 f�vrier 2007 Laurent Gomila

La fonction membre ostringstream::str() a deux surcharges : une sans param�tre qui renvoie le contenu du flux sous forme de string, et une autre qui accepte une cha�ne en param�tre pour r�initialiser le contenu du flux. Pour vider le flux il suffit donc d'appeler cette fonction avec comme param�tre la cha�ne vide.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <sstream> 
#include <string> 
  
std::ostringstream oss;  
std::string Fichier[10];  
  
// G�n�re une suite de noms de fichiers num�rot�s de 0 � 9  
for (int i = 0; i < 10; ++i)  
{  
    oss.str("");  
    oss << "Image_" << i << ".bmp";  
    Fichier[i] = oss.str();  
}
Note : on est souvent tent� d'utiliser la fonction clear, mais celle-ci n'a rien � voir : elle remet � z�ro les bits d'erreur du flux.

Mis � jour le 18 avril 2005 Laurent Gomila

De la m�me mani�re que dans Comment obtenir la repr�sentation hexad�cimale d'un entier ?, on peut obtenir la repr�sentation hexad�cimale d'un buffer de caract�res en repr�sentation hexad�cimale � l'aide du manipulateur std::hex.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <algorithm> 
#include <iomanip> 
#include <sstream> 
#include <string> 
  
std::string array_to_string(const unsigned char* buffer, std::size_t size) 
{ 
    std::ostringstream oss; 
  
    // Afficher en hexad�cimal et en majuscule 
    oss << std::hex << std::uppercase; 
  
    // Injecter tous les caract�res sous forme d'entiers dans le flux 
    std::copy(buffer, buffer + size, std::ostream_iterator<int>(oss, "")); 
  
    return oss.str(); 
}
On utilise ici std::copy et std::ostream_iterator<int> pour envoyer les �l�ments du buffer un � un au flux, sous forme d'entiers. Le flux �tant en mode hexad�cimal, ceux-ci seront chacun correctement convertis. Le manipulateur std::uppercase sert quant � lui � obtenir une repr�sentation des lettres hexad�cimales en majuscule.

Si l'on souhaite personnaliser la repr�sentation hexad�cimale, on peut d�velopper la boucle de copie comme ceci :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <algorithm> 
#include <iomanip> 
#include <sstream> 
#include <string> 
  
std::string array_to_string(const unsigned char* buffer, std::size_t size) 
{ 
    std::ostringstream oss; 
  
    // Afficher en hexad�cimal et en majuscule 
    oss << std::hex << std::uppercase; 
  
    // Remplir les blancs avec des z�ros 
    oss << std::setfill('0'); 
  
    for (std::size_t i = 0; i < size; ++i) 
    { 
        // S�parer chaque octet par un espace 
        if (i != 0) 
            oss << ' '; 
  
        // Afficher sa valeur hexad�cimale pr�c�d�e de "0x" 
        // setw(2) permet de forcer l'affichage � 2 caract�res 
        oss << "0x" << std::setw(2) << static_cast<int>(buffer[i]); 
    } 
  
    return oss.str(); 
} 
  
int main() 
{ 
    const std::size_t size = 5; 
    const unsigned char data[size] = {0x0C, 0x10, 0xFF, 0x00, 0xDA}; 
    std::cout << array_to_string(data, size) << '\n'; 
}
Le code ci-dessus produit le r�sultat suivant :
0x0C 0x10 0xFF 0x00 0xDA

Mis � jour le 17 octobre 2005 Aurelien.Regat-Barrel Laurent Gomila

Afin de rediriger l'entr�e ou l'une des sorties standard (cin, cout, cerr ou clog) vers un autre flux, il suffit de r�affecter leur streambuf (le streambuf est l'objet qui fait le lien entre le flux et ce vers quoi il lit / �crit).

Afin d'acc�der au streambuf d'un flux, il faut utiliser la fonction membre rdbuf (ses deux surcharges pour �tre pr�cis) :

Code c++ : S�lectionner tout
1
2
3
4
5
// R�cup�rer le streambuf d'un flux 
std::streambuf* std::ios::rdbuf(); 
  
// Changer le streambuf d'un flux 
void std::ios::rdbuf(std::streambuf*);
Ainsi, pour rediriger cout vers un fichier par exemple, il suffira de proc�der ainsi :

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <fstream> 
#include <iostream> 
  
int main() 
{ 
    std::cout << "Affichage sur la console"<< std::endl; 
  
    // Redirection de std::cout vers le fichier Toto.txt 
    std::ofstream Out("Toto.txt"); 
    std::streambuf* OldBuf = std::cout.rdbuf(Out.rdbuf()); 
  
    std::cout << "Affichage dans Toto.txt"<< std::endl; 
  
    // Restauration du streambuf initial de std::cout (affichage sur la console) 
    std::cout.rdbuf(OldBuf); 
  
    return 0; 
}
De cette mani�re vous n'�tes pas limit�, cette m�thode permet de rediriger n'importe quel flux vers n'importe quel autre.

� noter �galement que si vous ne souhaitez effectuer une telle redirection que ponctuellement et pour toute la dur�e de l'ex�cution, vous pouvez plus simplement utiliser une redirection au niveau de votre invite de commande (avec une syntaxe d�pendante de l'OS) :
>MonProgramme.exe > Toto.txt

Mis � jour le 3 f�vrier 2007 Cline

La STL propose deux classes pour it�rer sur les flux : istream_iterator et ostream_iterator (d�finies dans l'en-t�te <iterator>).

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
std::vector<int> Tab; 
Tab.push_back(1); 
Tab.push_back(3); 
Tab.push_back(6); 
  
// Plus besoin de boucle pour afficher les �l�ments du tableau : 
std::copy(Tab.begin(), Tab.end(), std::ostream_iterator<int>(std::cout, "\n"));
Dans cet exemple, l'it�rateur va parcourir les �l�ments du tableau un � un et utiliser l'op�rateur << pour les injecter dans le flux pass� en param�tre, en l'occurrence ici std::cout.
Le second param�tre de l'it�rateur est simplement le d�limiteur qui sera plac� entre chaque �l�ment.

Vous pouvez �galement utiliser les stream_iterator avec des classes quelconques, pourvu que leur op�rateur << soit correctement d�fini.

Cela marche aussi dans l'autre sens : avec un std::istream_iterator vous pourrez extraire des valeurs / objets d'un flux les unes apr�s les autres, et les placer par exemple dans un tableau.

Code c++ : S�lectionner tout
1
2
3
4
5
6
7
8
9
10
// On va extraire � partir d'un fichier, par exemple 
std::ifstream File("Data.txt"); 
  
// M�thode 1 : std::copy 
std::vector<MaClasse> Tab1; 
std::copy(istream_iterator<MaClasse>(File), istream_iterator<MaClasse>(), std::back_inserter(Tab1)); 
// std::back_inserter va remplacer les affectations par des push_back 
  
// M�thode 2 : utiliser le constructeur prenant une paire d'it�rateurs 
std::vector<MaClasse> Tab2(istream_iterator<MaClasse>(File), (istream_iterator<MaClasse>()));
Un istream_iterator construit par d�faut (comme le second ici) repr�sentera toujours la fin du flux.

La paire de parenth�ses a priori inutile autour du second istream_iterator est n�cessaire : sans cela le compilateur croirait � une d�claration de fonction. Pour �viter cela vous pouvez �galement d�clarer les variables correspondant aux it�rateurs en dehors de l'appel :

Code c++ : S�lectionner tout
1
2
3
istream_iterator<MaClasse> Begin(File); 
istream_iterator<MaClasse> End; 
std::vector<MaClasse> Tab2(Begin, End);
Pour les traitements sur des flux binaires (i.e. ouvertes avec l'option binary), il vaudra mieux utiliser std::istreambuf_iterator, qui n'appliquera pas de traitement sp�cial aux caract�res sp�ciaux.

Mis � jour le 3 f�vrier 2007 Laurent Gomila

Pour que le code suivant compile :

Code c++ : S�lectionner tout
1
2
3
4
5
istringstream s( "10" ); 
int n; 
if ( s >> n ) 
{ 
}
Le compilateur cherche � convertir l'expression s >> n en un bool�en. Il commence par rechercher un op�rateur applicable et trouve celui h�rit� de istream qui accepte un int. Cela revient donc � avoir le code suivant :

Code c++ : S�lectionner tout
1
2
3
4
5
istringstream s( "10" ); 
int n; 
if ( s.operator >>( n ) ) 
{ 
}
Cet op�rateur retourne une r�f�rence sur le flux utilis�, c'est-�-dire ici la variable s.
Le compilateur essaye alors de convertir cette r�f�rence (qui correspond � s apr�s l'appel de l'op�rateur >>, donc apr�s avoir tent� la conversion en int) en bool�en. istream ne d�finit pas d'op�rateur de conversion vers bool, mais une conversion implicite est possible gr�ce � l'op�rateur operator void*(). Ce dernier retourne un pointeur nul si les indicateurs d'�chec du flux sont positionn�s, ce qui est le cas en cas d'�chec de conversion. L'ensemble du processus effectu� par le compilateur correspond donc aux appels explicites suivants :

Code c++ : S�lectionner tout
1
2
3
4
5
istringstream s( "10" ); 
int n; 
if ( s.operator >>( n ).operator void*() != 0 ) 
{ 
}

Mis � jour le 19 octobre 2004 Aurelien.Regat-Barrel

Un tampon (buffer en anglais) est un moyen d'assouplir l'utilisation d'un syst�me lent par un autre plus rapide.

Au lieu d'acc�der directement au syst�me lent, l'utilisateur va simplement compl�ter une liste de demandes en attente.
Ainsi, l'utilisateur n'a plus besoin d'attendre le traitement, et peut poursuivre son activit�.

En C++, le flux de sortie standard, std::cout, utilise comme tampon un tableau de caract�res (cach� dans la biblioth�que standard).
Cela, parce que l'image affich�e � l'�cran n'est pas disponible en permanence. Il en est de m�me avec un fichier.
On retrouve cette id�e avec les files d'attente d'un p�age, ou celles � l'entr�e d'un routeur.

Le m�canisme d'un tampon est assez simple :
� chaque occasion qui se pr�sente, le syst�me lent regarde si le tampon contient au moins une entr�e. Si c'est le cas, il en retire une et la traite.
Laquelle est tir�e en premier d�pend du besoin, mais c'est souvent la plus ancienne.

En g�n�ral, un tampon est limit� en taille. Quand il est plein, deux traitements sont possibles : rejeter les nouvelles demandes ou mettre en attente l'utilisateur.
Un routeur rejette les demandes, ce qui provoque des messages d'erreur tels que "Cette page ne r�pond pas."
Le p�age va plutot prendre son temps, l'utilisateur se retrouve � attendre (c'est un bouchon).

Les tampons fonctionnent bien quand les demandes arrivent en rafales : une s�rie de demandes, puis rien pendant un temps largement suffisant pour toutes les traiter.

Mis � jour le 23 mai 2017 ternel

Un tampon permet de r�duire l'impact de la lenteur d'acc�s � une ressource, mais d�synchronise celle-ci de l'utilisateur.
Purger un tampon (flush en anglais) consiste � demander � la ressource de traiter toutes les demandes et attendre qu'il l'ait fait.

Cela permet de resynchroniser l'ensemble, par exemple pour s'assurer que le syst�me lent est bien dans l'�tat demand�.

Cela signifie ralentir le programme, certes, mais c'est un bon moyen de synchroniser des choses qui ne le sont pas de base, comme le flux de sortie standard et celui de saisie, ou encore les flux de sortie standard et d'erreur: std::cout et std::cerr.

En C++, il y a deux manipulateurs de flux de sortie qui sont utilisables pour cela: std::flush et std::endl.
La seule diff�rence entre les deux, c'est que endl ajoute un retour � la ligne avant de purger le buffer.

Ainsi cout << 2 << flush affiche 2 imm�diatement, parce que cela ajoute 2 au bout du buffer puis purge celui-ci.
De m�me, cout << endl se comporte comme cout << '\n' << flush.

Mis � jour le 23 mai 2017 ternel

Proposer une nouvelle r�ponse sur la FAQ

Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �a


R�ponse � la question

Liens sous la question
pr�c�dent sommaire suivant
 

Les sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.