8
votes

Pourquoi les ruisseaux en C ++?

Comme vous le savez tous, il existe des bibliothèques à l'aide de flux tels que iostream code> et fstream code>.

Ma question est la suivante: p>

  • Pourquoi les ruisseaux? Pourquoi n'ont-ils pas collé avec des fonctions similaires à code> imprimer code>, fgets code> et ainsi de suite (par exemple)? Li> ul>

    Ils nécessitent leurs propres opérateurs et >> code> mais tout ce qu'ils font pourraient être mis en œuvre dans des fonctions simples telles que ci-dessus, aussi la fonction p >

    cout << "Hello World";
    


3 commentaires

L'efficacité n'est pas vraiment une préoccupation, car 99% du temps seront dépensés dans les mêmes appels d'exploitation pour imprimer à la console.


-1 Hey Boy, je suppose que vous êtes un débutant dans le monde de C ++. Comment pouvez-vous dire que c'est moins efficace, si vous ne savez pas? Avant été critique, s'il vous plaît, apprenez et soyez modeste.


Sur une note connexe, le boost.format ( Boost. Org / DOC / LIBS / 1_42_0 / LIBS / FORMAT / DOC / FORMAT.HTML ) La bibliothèque fournit un type de formatage de type de type PrintF.


14 Réponses :


7
votes

Les flux C ++ sont de type Safe. En C, si vous dites:

double d = 1.23;
printf( "%d", d );


0 commentaires

2
votes

Les flux peuvent être chaînés ensemble xxx


2 commentaires

Alors pourrait être des méthodes: out.print ("Bonjour"). Imprimer ("") .print ("World")


STD :: COUT.OPERATOR << ("Bonjour"). Opérateur << ("") .Opérateur << ("World");



5
votes

Printf n'est pas en sécurité pour un. L'interface COUT est également plus générique, ce qui permet à une grande quantité de choses indisponibles avec la version Printf. Un excellent exemple est que votre opérateur de flux de vos types est, si vous faites le bien, vous référez-vous à STD :: Onetream en tant que flux, pas de cout. Ainsi, vous pouvez modifier la destination de la sortie simplement en utilisant un flux différent. Pour ce faire avec PrintF, vous devez faire beaucoup de plate-forme dépendante de la plate-forme dépendante des poignées de sortie.

Je pense aussi que toutes ces abstractions de chaîne en C ++ compilent toutes les appels de fonction standard (moins efficaces) en binaires.

pense que tout ce que vous voulez. Jusqu'à ce que vous testez réellement votre hypothèse, votre opinion ne tiendra pas beaucoup de poids. De plus, vous devez considérer la perte d'abstraction, quelque chose qui est généralement beaucoup plus important dans le développement logiciel moderne.


0 commentaires

1
votes

Le flux comme syntaxe avec opérateur <<< / code> et opérateur >> permet une belle concaténation. XXX

VS < Pré> xxx

De plus dans la première approche, il faut toujours penser au type, tandis que dans l'approche de flux, le type ne doit pas être spécifié.


0 commentaires

24
votes

Les flux ont une meilleure sécurité de type.

par exemple printf ("% s", a); code> peut aller horriblement mal si a code> est un entier. COUT n'a pas ce problème. P>

Un autre problème est que les flux sont mieux conformes aux méthodologies de conception orientées objet. P>

Par exemple, vous avez une application simple qui écrit certaines sorties, puis vous souhaitez que la sortie accède à un fichier au lieu de la console. Avec C Appels, vous devrez remplacer tous les appels à Printf code> aux appels vers FPRRINTF CODE> et veillez à conserver le fichier * code> sur le manière. Avec des flux, vous venez de changer la classe de béton du flux que vous utilisez et c'est tout, la plupart du code restent identiques comme: P>

void doSomething(ostream& output)
{
   output << "this and that" << a;
}

doSomething(cout);
doSomething(ofstream("c:\file.txt"));


2 commentaires

Bien entendu, les compilateurs modernes ont été étendus (pas de manière compatible des normes) pour prendre en charge le type de vérification des chaînes de format Printf.


"Avec C Appels, vous devrez remplacer tous les appels à Printf aux appels à FPRRTINF" - la situation n'est pas si mauvaise, par exemple. Vous pouvez faire la redirection de Stream Freopen ("Sortie.txt", "W", stdout); et éviter le remplacement



1
votes

effectivement xxx

semble beaucoup plus intuitif pour moi que xxx

si vous ne semblez jamais de printf avant, il n'y a pas de Comment vous allez savoir ce que cela fait.

dans les deux cas, xxx

(en plusieurs langues, y compris Python : :() fait beaucoup plus sens :)


6 commentaires

Python a Imprimer "Test:% D"% Test aussi, et il est très nécessaire pour un formatage plus compliqué.


@Unclebens: True, et il est très malheureux, ils ont choisi d'utiliser des chaînes de format de style C, surtout nécessitant la saisie d'une langue dynamique ...


Si vous n'avez jamais vu des ruisseaux C ++ auparavant, c'est encore pire: vous pensez que vous effectuez un peu de décomposition!


@Blueraja La Licorne verte: Je pense que, par exemple, printf ("% - 04d", test) est plus lisible que l'équivalent C ++.


Vous pouvez utiliser le spécificateur % s pour tout type de python. D'autre part Imprimer "Test:" + Test ne semble pas fonctionner si le test est un entier.


@ el.pecAdo: cela ne confondra que ceux qui ont écrit en C mais pas C ++. Faire une décision de conception linguistique simplement parce que "Nous ne voulons pas confondre les utilisateurs provenant d'une autre langue" est un excellent moyen de faire dupliquer les erreurs d'autres langues (voir le commutateur blocs, par exemple)



9
votes

Pour un, il vous permet de profiter du modèle d'objet C ++ pour créer des fonctions qui ne se soucient pas de savoir s'ils écrivent à la sortie standard, à un fichier ou à une prise réseau (si vous avez une prise réseau qui dérive de < code> ostream ). E. g. xxx

et similaire pour les flux d'entrée.

Les flux ont également un avantage en matière de saisie et de sortie d'objets. Que se passerait-il si vous vouliez lire dans un objet avec scanf ? xxx

même s'il y avait un spécificateur approprié, comment SCANF SAVOIR Comment remplir les membres de l'objet? Avec des flux C ++, vous pouvez surcharger opérateur <<< / code> et écrire xxx

et cela fonctionnera. De même pour std :: COUT << OBJ , vous pouvez donc écrire le code de sérialisation de l'objet au même endroit et ne pas avoir à vous en soucier de cela ailleurs.


2 commentaires

Une prise réseau qui dérive de iostream est vraiment quelque chose que je voudrais voir :)


@shoosh boost :: asio :: ip :: tcp :: iostream ?



1
votes

C ++ vous permet d'utiliser Printf, à la manière. Donc, si vous aimez ça, allez-y et utilisez-le.

Les flux sont utilisés pour beaucoup plus que d'écrire une sortie à la console. Ce sont une solution de mise en mémoire tampon de données à usage général pouvant être appliquée à tout à partir de la sortie d'écran à la gestion des fichiers au trafic réseau et aux interfaces de périphérique d'entrée. Vos trucs peuvent écrire à (ou lire) les flux sans se soucier de l'endroit où ces données vont réellement aller.

Disons que vous avez un objet complexe que vous souhaitez pouvoir écrire sur la console de sortie, à un fichier journal et dans une fenêtre de débogage de la fenêtre. Allez-vous écrire trois fonctions qui font presque exactement la même chose, ou allez-vous écrire une fonction à laquelle vous passez un flux de sortie (Y)?


0 commentaires

2
votes

Un autre avantage des flux est qu'ils ont été faits pour être extensibles. Avec des flux, vous pouvez faire fonctionner vos classes définies par l'utilisateur, comme des types intégrés: xxx pré>

et maintenant, vous pouvez imprimer un foo comme n'importe quoi d'autre: P>

int n = ...
foo f = ...

cout << n << ": " << f << endl;


0 commentaires

0
votes

J'utilise toujours Printf, principalement parce qu'il est facile de contrôler le format de sortie.

Pour moi, le type de sécurité n'est pas un avantage principal ici car il peut être facilement capturé par test, étant donné qu'un programme basé sur la console est beaucoup plus facile à tester avec des applications basées sur l'interface utilisateur ou Web. Si vous ne testez pas de test, des bugs plus graves peuvent surmonter la vérification de l'heure de la compilation.

Je ne suis pas non plus d'accord avec une autre raison pour laquelle le flux de sinistres est plus flexible en raison de l'interchangeabilité. C'est équivalent à recommander d'utiliser FPRRTINF (Fout, ...) pour l'interchangeabilité. Si vous devez rediriger la sortie, utilisez du tuyau. Si vous êtes dans une bibliothèque, pourquoi ne pas simplement retourner une chaîne et laisser l'appelant décider où il va?


2 commentaires

Utilisez un tuyau - tout n'est pas une commande comme une application. Renvoie une chaîne - pas très efficace.


Shoosh, juste de la curiosité, comment pouvez-vous retourner une chaîne en C de la fonction? Je veux dire s'il a été alloué là-bas comme (Statique Char * Mystring), vous ne rentreriez qu'un pointeur. Si vous voulez dire String de STL, vous ne renvoyez que l'objet qui représente une chaîne, une chaîne est détenue ailleurs - aucune perte d'efficacité



3
votes

En plus d'être de type sûr et polymorphe, les flux sont plus portables. Sur certains systèmes Printf avec une longue nécessité "% D" et sur certains systèmes, il nécessite "% LD".


3 commentaires

La conformité nécessite toujours % ld , mais le l ne fait rien sur certaines plates-formes.


J'ai changé beaucoup de code follement compliqué pour contourner cela pour utiliser des flux sans jamais réaliser cela!


+1 Un jour, j'ai perdu une longue période jusqu'à ce que j'utilise du débogueur pour regarder



0
votes

stringstream est plus sûr que snaprintf / SSCANF car il évite complètement la possibilité de débordement tampon (même "défaillances gracieuses").


0 commentaires

0
votes

Les flux fonctionnent avec des modèles, tandis que printf / scanf ne pas.


0 commentaires

2
votes

C ++ iostreams sont ridiculement inefficaces (dans la plupart des implémentations que je connais de). Souvent, ce n'est pas une préoccupation, mais quand c'est, la bibliothèque est fondamentalement inutile. C'est aussi un bon point que la syntaxe est inintuciante (et très, très verbeuse). La bibliothèque est complexe et difficile à prolonger. Ce n'est pas très flexible non plus. Lorsqu'il est contrasté contre quelque chose comme la STL, iostreams ressemble vraiment à un mauvais rêve. Mais c'est ici, et nous sommes bloqués avec ça.

La raison pour laquelle c'est ici, et la raison à laquelle on dirait que cela, est qu'il a été développé plus tôt, avant que C ++ ne soit une langue mature. Avant d'avoir eu des décennies d'expérience nous disant ce qui est, et ce n'est pas la bonne conception de la bibliothèque. Avant que quiconque savait vraiment quelles étaient les options.

C ++ avait besoin d'une bibliothèque d'E / S qui était mieux que c. Et de certaines manières importantes, C ++ iostreams sont mieux. Ils sont sécurisés et extensibles, car d'autres ont mentionné. En mettant en œuvre un seul opérateur, je peux imprimer une classe définie par l'utilisateur. Cela ne pouvait pas être fait avec printf . Je n'ai pas non plus à vous soucier de recevoir des spécificateurs de format incorrect et d'imprimer des ordures en raison d'un manque de sécurité de type.

Ces choses nécessaires doivent être corrigées. Et hé, dans les premiers jours, les fonctions virtuelles et la surcharge de l'opérateur étaient la merde . Il avait l'air cool. Bien sûr, les bibliothèques voulaient utiliser ces fonctionnalités.

La bibliothèque iostreams est un compromis entre:

  • quelque chose de plus sûr et plus extensible que celui de C stdio.h
  • Quelque chose d'efficacité
  • quelque chose de bien conçu et intuitif
  • une bibliothèque qui a réellement existé au moment où C ++ était normalisé. (Ils ont dû ajouter quelque chose , ils devaient donc choisir entre les candidats qui existaient réellement à l'époque.)

    La bibliothèque ne réussit pas toutes ces choses, et je pense qu'aujourd'hui, avec nos décennies d'expérience avec la langue, nous aurions pu concevoir une bibliothèque bien meilleure. Mais de retour au milieu des années 90, quand ils recherchaient une bibliothèque d'E / S à ajouter, c'était le meilleur qu'ils pouvaient trouver.


0 commentaires