2010-08-29 26 views
16

J'ai regardé beaucoup de code fait récemment par d'autres et j'ai remarqué que tout le monde utilise beaucoup les fonctions C de «printf», mais les fonctions C++ apprises à l'école (cout, spécifiquement) ne semblent pas si populaires.Les fonctions d'E/S au format C (printf, sprintf, etc.) sont-elles plus populaires que IOStream, et si oui, pourquoi?

Est-ce une observation valide, et y a-t-il une raison à cela? Convention?

Merci,

R

+9

'Tout le monde semble un peu extrême. –

+0

Voir aussi: http://stackoverflow.com/questions/119098/which-io-library-do-you-use-in-your-c-code/119194#119194 –

+0

qui sont tout le monde et vous ne devriez pas faire un tel hypothèses générales. –

Répondre

24

Personnellement, j'utilise printf sur les choses iostream (comme cout) parce que je pense que c'est plus clair.

Lorsque vous formatage avec iostream, vous devez << toutes sortes de bizarreries comme et setf. Je ne peux jamais me souvenir de l'espace de noms dans lequel tous ces trucs vivent, et encore moins de ce que tout cela fait. Même quand je le fais, je suis déçu de voir à quel point le code est détaillé et non intuitif.

Les options de formatage avec printf peuvent sembler illisibles au premier abord, mais elles sont concises, clairement documentées dans une seule page de manuel et communes à un large éventail de langues.

Une autre est que advanage printf est apatride: Contrairement aux cout, je ne ai pas besoin de se rappeler que les fonctions membres ont été invités à printf, ou qui Byzantin concoction de drapeaux a été << « ed en elle. C'est un gros plus pour la lisibilité.

+11

+1 pour indiquer la distinction entre l'état et l'état. C'est vraiment une bonne chose quand vous n'avez pas à vous soucier de savoir si vos tentatives de sortie de données vont se chevaucher. – JustJeff

+6

Une chose à souligner est que vous pouvez utiliser des drapeaux de style printf avec des chaînes C++ en utilisant 'boost :: format' – bdonlan

4

Il y a plusieurs critiques du système de flux standard - notamment qu'il est généralement pas aussi performant que le système C, et qu'ils ne permettent pas réordonner des éléments être formaté, ce qui peut rendre la localisation plus difficile.

Personnellement, j'utiliser les flux pour la plupart tout, parce qu'ils me permettent d'avoir une écriture de fonction à une console, un fichier ou une chaîne, sans avoir à modifier la fonction.

+4

Vous pouvez utiliser des flux avec des spécificateurs de format de style printf avec boost :: format', vous savez :) – bdonlan

+2

Passer un 'FILE *' comme paramètre serait aussi simple que de passer un paramètre 'ostream'. Autoriser 'fprintf' à écrire sur une console ou un fichier. – gwell

+2

@gwell: Dernière vérification, je ne peux pas écrire un FICHIER * dans une mémoire tampon. –

5

Je pense que le goût est une raison possible. Personnellement, je trouve cela:

printf("%8d: %s\n", customer->id, customer->name); 

plus lisible que ceci:

std::cout << customer->id << ": " << customer->name << std::endl; 

Il y a aussi le problème avec la localisation. printf permet de modifier la mise en forme pour s'adapter à d'autres langages et cultures UI, ce qui devient une corvée majeure avec iostreams, sauf si vous utilisez quelque chose comme la bibliothèque Boost Format.

+0

Bizarre réponse. La prise en charge des locales est en fait un point où les iostreams sont significativement meilleurs que printf * et * pas vraiment plus difficiles à utiliser. –

2

Là où je travaille, nous utilisons printf la mise en forme de style. C'est parce que nous avions l'habitude de faire un usage intensif de la classe MFC CString et de sa méthode printf -style Format. Nous avons éliminé progressivement les MFC, mais nous n'avons pas modifié notre approche de formatage des chaînes.

Comme pour lequel on est mieux conçu, voir Who architected/designed C++'s IOStreams, and would it still be considered well-designed by today's standards?

+0

+1 pour la bonne référence croisée. –

0

Les fonctions de la famille printf et scanf ont deux problèmes majeurs: la sécurité de type et de sécurité de la mémoire. Il est assez facile de faire une différence entre la chaîne de spécification et la liste d'arguments de longueur variable qui suit.En outre, les dépassements de tampon via scanf constituent une vulnérabilité de sécurité classique. En bref, ne les utilisez pas.

Les flux C++ offrent la sécurité du type et de la mémoire, ainsi que l'extensibilité de la mise en forme. Ils sont beaucoup plus puissants et généralement plus faciles à utiliser que printf et scanf. De plus, comme suggéré par ShaderOp, la bibliothèque de formats de Boost offre la même sécurité, mais rend les anciens programmeurs C plus à l'aise.

+1

C++ est assez bas niveau que vous pouvez toujours vous tirer dans le pied, même avec des flux et "type de sécurité" - par exemple, 'cout << * (int *) &foo;' D'un autre côté, tout compilateur C décent délivrera avertissements pour les incompatibilités de type chaîne de caractères 'printf', donc je ne pense pas que 'safety' soit un argument valable pour l'un sur l'autre. D'autre part, les flux C++ ont au moins 2 inconvénients majeurs sur 'printf' (en particulier' printf' avec les extensions de localisation XSI): facilité de traduction des messages à des fins de localisation et apatridie (potentiellement un gros problème avec les threads). –

+0

Le compilateur peut uniquement vérifier votre chaîne de format si elle sait quelle est votre chaîne de format. Mais l'un des avantages de 'printf' sur iostreams est que vous pouvez configurer la chaîne de format lors de l'exécution. Donc, la sécurité de type semble certainement être un argument valable pour moi. –

+3

@R tout compilateur C++ décent attrapera la distribution C-style et émettra un avertissement –

1

Je vais deviner printf est plus largement utilisé, car

  • il était utilisé depuis quelques très années avant que les compilateurs C de et cours d'eau sont apparus
  • C est utilisé plus
  • C++ Beaucoup d'E/S a été fait pour des choses comme l'API Windows, pour laquelle printf est un ajustement naturel entre Open/Read/Write/Close/etc