33 votes

Quelle bibliothèque d'E/S C doit être utilisée dans le code C++ ?

Dans le nouveau code C++, j'ai tendance à utiliser la bibliothèque C++ iostream au lieu de la bibliothèque C stdio.

J'ai remarqué que certains programmeurs semblent s'en tenir à stdio, en insistant sur le fait que c'est plus portable.

Est-ce vraiment le cas ? Qu'est-ce qui est le mieux à utiliser ?

39voto

Loki Astari Points 116129

Pour répondre à la question initiale :
Tout ce qui peut être fait avec stdio peut être fait avec la bibliothèque iostream.

Disadvantages of iostreams: Its verbose
Advantages    of iostreams: Its easy to extend for new non POD types.

L'avancée du C++ par rapport au C était la sécurité des types.

  • iostreams a été conçu pour être explicitement sûr du type. Ainsi, l'affectation à un objet vérifie explicitement le type (au moment de la compilation) de l'objet auquel il est affecté (générant une erreur de compilation si nécessaire). Cela permet d'éviter les dépassements de mémoire à l'exécution ou l'écriture d'une valeur float dans un objet char, etc.

  • scanf()/printf() et la famille, d'un autre côté, dépendent du programmeur pour que la chaîne de format soit correcte et il n'y avait pas de vérification de type (je crois que gcc a une extension qui aide). En conséquence, c'était la source de nombreux bogues (car les programmeurs sont moins parfaits dans leur analyse que les compilateurs [je ne vais pas dire que les compilateurs sont parfaits, juste meilleurs que les humains]).

Juste pour clarifier les commentaires de Colin Jensen.

  • Les bibliothèques iostream sont stables depuis la publication de la dernière norme (j'ai oublié l'année exacte, mais cela fait environ 10 ans).

Pour clarifier les commentaires de Mikael Jansson.

  • Les autres langages qu'il mentionne et qui utilisent le style de format ont des sauvegardes explicites pour éviter les effets secondaires dangereux de la bibliothèque C stdio qui peuvent (en C mais pas dans les langages mentionnés) provoquer un crash à l'exécution.

N.B. Je suis d'accord pour dire que la bibliothèque iostream est un peu trop verbeuse. Mais je suis prêt à supporter cette verbosité pour assurer la sécurité de l'exécution. Mais nous pouvons atténuer cette verbosité en utilisant Bibliothèque de formats Boost .

#include <iostream>
#include <iomanip>
#include <boost/format.hpp>

struct X
{  // this structure reverse engineered from
   // example provided by 'Mikael Jansson' in order to make this a running example

    char*       name;
    double      mean;
    int         sample_count;
};
int main()
{
    X   stats[] = {{"Plop",5.6,2}};

    // nonsense output, just to exemplify

    // stdio version
    fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
            stats, stats->name, stats->mean, stats->sample_count);

    // iostream
    std::cerr << "at " << (void*)stats << "/" << stats->name
              << ": mean value " << std::fixed << std::setprecision(3) << stats->mean
              << " of " << std::setw(4) << std::setfill(' ') << stats->sample_count
              << " samples\n";

    // iostream with boost::format
    std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n")
                % stats % stats->name % stats->mean % stats->sample_count;
}

16voto

Mikael Jansson Points 3234

C'est juste trop verbeux.

Réfléchissez à la construction iostream pour faire ce qui suit (de même pour scanf) :

// nonsense output, just to examplify
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
    stats, stats->name, stats->mean, stats->sample_count);

Cela nécessiterait quelque chose comme :

std::cerr << "at " << static_cast<void*>(stats) << "/" << stats->name
          << ": mean value " << std::precision(3) << stats->mean
          << " of " << std::width(4) << std::fill(' ') << stats->sample_count
          << " samples " << std::endl;

Le formatage des chaînes de caractères est un cas où l'orientation objet peut, et doit, être évitée en faveur d'un DSL de formatage intégré aux chaînes de caractères. Considérez le langage Lisp format le formatage de style printf de Python, ou PHP, Bash, Perl, Ruby et leur intrapolation de chaînes de caractères.

iostream pour ce cas d'utilisation est malavisée, au mieux.

14voto

KK. Points 176

Le site Bibliothèque de formats Boost fournit une alternative orientée objet et sécurisée en termes de type pour le formatage des chaînes de caractères de type printf. C'est un complément aux iostreams qui ne souffre pas des problèmes habituels de verbosité grâce à l'utilisation intelligente de l'opérateur%. Je recommande de l'envisager plutôt que d'utiliser printf en C si vous n'aimez pas le formatage avec l'opérateur<< de iostream.

9voto

Colin Jensen Points 1555

À l'époque, le comité des normes C++ ne cessait de modifier le langage et iostreams était une cible mouvante. Si vous utilisiez iostreams, vous aviez alors la possibilité de réécrire des parties de votre code tous les ans environ. Pour cette raison, j'ai toujours utilisé stdio qui n'a pas changé de manière significative depuis 1989.

Si je faisais des choses aujourd'hui, j'utiliserais iostreams.

6voto

Adam Pierce Points 12801

Si, comme moi, vous avez appris le C avant d'apprendre le C++, les bibliothèques stdio semblent plus naturelles à utiliser. Il y a des avantages et des inconvénients à utiliser iostream ou stdio, mais printf() me manque quand j'utilise iostream.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X