On ne peut utiliser l'opérateur >>
que pour lire sur un fichier
contenant des données respectant un certain format (par exemple, si on
sait que chaque ligne contient un entier, un espace, une chaîne de
caractères, un espace et un nombre flottant). Si l'on ignore a
priori le contenu d'un fichier, on doit effectuer une lecture octet
par octet et confier au programme, éventuellement, l'interprétation de
ces octets. C'est la seule façon pour lire un fichier ``binaire'',
contenant par exemple une image. Les méthodes employées utilisent toutes
le type char qui représente les caractères comme des octets.
La méthode int get() permet de lire un caractère et retourne la valeur entière de ce caractère ou bien la constante EOF si la fin du flot est atteinte. La méthode istream& get(char& c) permet de lire un caractère (et place sa valeur dans le paramètre passé par référence), mais peut échouer.
De façon symétrique, la méthode ostream& put(char c), écrit un caractère sur le flot, et peut échouer. La fonction suivante combine get et put pour copier un flot d'octets sur un autre ; elle peut être appelée aussi bien pour copier cin sur cout que pour copier un fichier sur un autre :
void copie(istream& in, ostream& out) { char c; while (in.get(c)) out.put(c); } int main() { copie(cin, cout); ifstream ifs("original"); ofstream ofs("copie"); if (ifs && ofs) copie(ifs, ofs); return 0; }
Plus généralement, il existe des méthodes qui permettent de lire et d'écrire un nombre limité d'octets en les transférant vers ou depuis un tableau de caractères, passé par adresse. Il s'agit des méthodes istream& read(char*, int) et write(const char*, int). Elles permettent par exemple, à l'aide d'une coercition et du passage d'un entier par adresse, de lire ou d'écrire la représentation binaire (en mémoire) d'un entier :
typedef char *octets; typedef const char *const_octets; int i; in.read(octets(&i), sizeof i); // lecture binaire out.write(const_octets(&i), sizeof i); // écriture binaire
La coercition octets(&i)
permet de ré-interpréter la
valeur de l'expression &i
, qui est de type int *, comme
étant une valeur de type octets, c'est-à-dire char *,
grâce au typedef précédent. Signalons que sizeof i est
une nouvelle catégorie d'expression, et qu'il n'est pas nécessaire de
placer son argument i entre parenthèses ; sa valeur est le
nombre d'octets occupés en mémoire par son argument.