Question

L'E / S de fichier C ++ est plus dure que celle d'E / S de fichier C. Donc, en C ++, créer une nouvelle bibliothèque pour les entrées / sorties de fichiers est utile ou pas? Je veux dire <fstream> Quelqu'un peut-il indiquer s'il existe des avantages en termes d'E / S de fichier C ++?

Était-ce utile?

La solution

Opinion

Je ne connais aucun projet réel utilisant des flux C ++. Ils sont trop lents et difficiles à utiliser. Il existe plusieurs bibliothèques plus récentes comme FastFormat et le Boost version qui prétend être meilleure, il y avait un article à ce sujet dans le dernier magazine de surcharge ACCU. Personnellement, je me sers de la bibliothèque c FILE depuis environ 15 ans en C ++ et je ne vois encore aucune raison de changer.

Vitesse

Voici un petit programme de test (je frappe rapidement) pour montrer le problème de vitesse de base:

#include <stdio.h>
#include <time.h>

#include<iostream>
#include<fstream>

using namespace std;

int main( int argc, const char* argv[] )
    {
    const int max = 1000000;
    const char* teststr = "example";

    int start = time(0);
    FILE* file = fopen( "example1", "w" );
    for( int i = 0; i < max; i++ )
        {
        fprintf( file, "%s:%d\n", teststr, i );
        }
    fclose( file );
    int end = time(0);

    printf( "C FILE: %ds\n", end-start );

    start = time(0);
    ofstream outdata;
    outdata.open("example2.dat");
    for( int i = 0; i < max; i++ )
        {
        outdata << teststr << ":" << i << endl;
        }
    outdata.close();
    end = time(0);

    printf( "C++ Streams: %ds\n", end-start );

    return 0;
    }

Et les résultats sur mon PC:

C FILE: 5s
C++ Streams: 260s

Process returned 0 (0x0)   execution time : 265.282 s
Press any key to continue.

Comme nous pouvons le constater, cet exemple simple est 52 fois plus lent. J'espère qu'il y a moyen de le faire plus vite!

REMARQUE: dans mon exemple, remplacer endl par "\ n" améliore les flux C ++, le ralentissant 3 fois plus lentement que les flux FILE * (merci jalf ), il existe peut-être des moyens de l'accélérer.

Difficulté d'utilisation

Je ne peux pas nier que printf () n'est pas concis, mais il est plus souple et plus simple à comprendre, une fois que vous avez dépassé le WTF initial pour les codes de macros.

double pi = 3.14285714;

cout << "pi = " << setprecision(5)  << pi << '\n';
printf( "%.5f\n", pi );

cout << "pi = " << fixed << showpos << setprecision(3) << pi << '\n'; 
printf( "%+.3f\n", pi );

cout << "pi = " << scientific << noshowpos << pi<< '\n';
printf( "%e\n", pi );

La question

Oui, une meilleure bibliothèque C ++ est peut-être nécessaire. De nombreux FastFormat sont cette bibliothèque, seul le temps nous le dira.

dave

Autres conseils

Pour moi, bannir les dépassements de tampon semble être une grande victoire pour C ++.

Veuillez regarder

http://www.ddj.com/cpp/184403651

alors vous préférerez les E / S C ++ aux E / S C.

En bref, C est préférable si vous connaissez la taille des données avant lecture ou écriture et pour la vitesse. C ++ est préférable si vous ne connaissez pas la taille des données et pour un code efficace.

En réponse à la réponse de David Allan Finch, j'ai corrigé une erreur dans son code d'analyse comparative (il vidait le flux dans la version C ++ après chaque ligne) et refaisais le test:

La boucle C ++ ressemble maintenant à ceci:

start = time(0);
{
    ofstream outdata("example2.txt");
    for( int i = 0; i < max; i++ )
    {
        outdata << teststr << ":" << i << "\n"; // note, \n instead of endl
    }
}
end = time(0);

Je lance 10000000 itérations (10 fois plus que dans le code original, parce que sinon, les nombres sont tout simplement trop petits pour la résolution moche de time () qui ne nous donne rien de significatif)) Et le résultat est:

G++ 4.1.2:
C FILE: 4s
C++ Streams: 6s

MSVC9.0:
C FILE: 10s
C++ Streams: 23s

(remarque, la version MSVC a été exécutée sur mon ordinateur portable avec un disque dur nettement plus lent)

Mais cela nous donne une différence de performance de 1,5-2,3x, selon l’implémentation. et d'autres facteurs externes.

Les différences de performances entre le formatage des E / S de style printf () / fwrite et le formatage des flux C ++ IO dépendent énormément de la mise en œuvre. Certaines implémentations (Visual C ++ par exemple) construisent leurs flux d'E / S par-dessus les objets FILE *, ce qui tend à accroître la complexité d'exécution de leur implémentation. Notez cependant qu’il n’existait aucune contrainte particulière pour implémenter la bibliothèque de cette manière.

À mon avis, les avantages de l'E / S C ++ sont les suivants:

  • Tapez safety comme déjà indiqué précédemment.
  • Flexibilité de mise en œuvre. Le code peut être écrit pour effectuer un formatage spécifique ou être entré dans ou à partir d'un objet générique ostream ou istream. L'application peut ensuite invoquer ce code avec tout type d'objet de flux dérivé. Si le code que j'ai écrit et testé sur un fichier doit maintenant être appliqué à un socket, un port série ou un autre type de flux interne, vous pouvez créer une implémentation de flux spécifique à ce type d'E / S. Étendre les E / S de style C de cette manière n’est même pas possible.
  • Flexibilité dans les paramètres régionaux: l'approche C consistant à utiliser un seul paramètre régional global est, à mon avis, gravement défaillante. J'ai rencontré des cas où j'appelais du code de bibliothèque (une DLL) qui modifiait les paramètres régionaux globaux situés sous mon code et perturbait complètement ma sortie. Un flux C ++ vous permet d'imbuer () n'importe quelle locale sur un objet de flux.

std :: ifstream et std :: ofstream sont déjà dans la bibliothèque stl. Vous n'êtes pas obligé de créer le vôtre.

Le principal avantage est que toutes les sorties et les entrées sont de type sécurité.

C et C ++ sont deux langages différents. Il faut un certain temps pour s’habituer au fichier C ++ io, mais une fois que vous utilisez des algorithmes, des exceptions, etc., ils ont tendance à se mettre en place très naturellement.

Chaque fois que je dois prendre des entrées / donner des sorties dans un fichier en C ++, j'utilise seulement deux lignes.

freopen("input.txt","r",stdin); // for input from file
freopen("output.txt","w",stdout);// for output from file

Vous pouvez maintenant analyser les variables comme vous le feriez normalement depuis la console et tout ce que vous imprimerez en sortie sera affiché dans le fichier output.txt.

Donc, je ne pense pas que les entrées / sorties de fichiers en c ++ soient difficiles, c’est plus simple que c.

Beaucoup. Des inconvénients aussi. Voir la FAQ sur le langage C ++ pour plus de détails. En bref: types de sécurité et types définis par l'utilisateur.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top