2010-03-02 15 views
0

Je travaille sur le tri de plusieurs fichiers volumineux en C++. J'ai un fichier texte contenant les noms de tous les fichiers d'entrée, un sur chaque ligne. Je voudrais lire les noms de fichiers dans un à la fois, les stocker dans un tableau, puis créer un fichier avec chacun de ces noms. À l'heure actuelle, j'utilise fopen et fread, qui nécessitent des tableaux de caractères (j'essaie d'optimiser la vitesse), donc mes noms de fichiers sont lus dans un tableau de tableaux de caractères. Ces tableaux, cependant, doivent avoir une taille maximale fixée à l'avance, donc si le nom de fichier est plus petit que le maximum, le reste est plein d'ordures. Ensuite, lorsque j'essaie d'utiliser ce tableau comme nom de fichier dans fopen(), il ne reconnaît pas le fichier car il contient des données parasites à la fin de la chaîne. Comment puis-je résoudre ce problème? Voici mon code:Créer des fichiers à partir de noms de fichier dans un autre fichier C++

#include <iostream> 
#include <fstream> 
#include <string> 
#include "stdafx.h" 
#define NUM_INPUT_FILES 4 

using namespace std; 



FILE *fp; 
unsigned char *buff; 
FILE *inputFiles[NUM_INPUT_FILES]; 


int _tmain(int argc, _TCHAR* argv[]) 
{ 


    buff = (unsigned char *) malloc(2048); 
    char j[8]; 
    char outputstring[] = "Feelings are not supposed to be logical. Dangerous is the man who has rationalized his emotions. (David Borenstein)"; 

    fp = fopen("hello.txt", "r"); 

    string tempfname[NUM_INPUT_FILES]; 
    //fp = fopen("hello.txt", "r"); 
    for(int i=0;i<NUM_INPUT_FILES;i++) 
    { 
     fgets(tempfname[i], 20, fp); 
     cout << tempfname[i]; 
    } 
    fclose(fp); 

    for(int i=0; i<NUM_INPUT_FILES;i++) 
    { 
     fp = fopen(tempfname[i], "w"); 
     //fwrite(outputstring, sizeof(char), sizeof outputstring/sizeof(char), fp); 
     if(fp) 
     { 
      fclose(fp);} 
     else 
      cout << "sorry" << endl; 
    } 


    return 0; 
} 

, comment puis-je trouver aussi la taille d'un tampon pour écrire avec fwrite()?

Merci beaucoup, bsg

Répondre

5

Comme Don Knuth dit, l'optimisation prématurée est la racine de tous les maux.

Vos noms de fichiers ne sont absolument pas le goulot d'étranglement! Utilisez simplement std::string pour eux. Toutefois, vous devrez remplacer fp = fopen(tempfname[i], "w"); par fp = fopen(tempfname[i].c_str(), "w");.

1

vous utilisez des idiomes de type C, ce serait mieux si vous allez gérer les fichiers google en C++. ce qui est un peu étrange de commencer avec si vous êtes un programmeur C, mais il vaut vraiment la peine de travailler à faire la façon C++

2

Oubliez optomizing à ce stade.
Utilisez std::vector<std::string> pour que votre programme fonctionne. Une fois que cela fonctionne, si la vitesse est vraiment cruciale alors vous pouvez revenir en arrière et la changer

0

Si vous lisez les fichiers ligne par ligne, vous pouvez alors allouer seulement la quantité d'espace pour chaque ligne qui est nécessaire et construisez votre tableau de lignes de cette façon.

Je peux comprendre que cela peut ne pas être assez rapide pour vous, donc comme une alternative. je suggère

  1. obtenir la taille du fichier
  2. allouer un tampon de cette taille
  3. lire le fichier entier dans la mémoire tampon.
  4. balayer la mémoire tampon remplaçant \ r \ n avec \ 0 et mémoriser le début de chaque ligne dans un vecteur de type char *
1

Vous avez besoin d'ajouter un octet nul et la bande de la nouvelle ligne, donc écrire une boucle for dans votre première boucle for qui recherche la nouvelle ligne et la remplace par un octet nul.

Bien que les autres ont raison, vous êtes sérieusement mal orienté dans vos tentatives d'optimisation.

Et assurez-vous que vous libérez ce que vous malloc. Une autre bonne raison pour laquelle vous devriez utiliser le STL.

0

Je suis avec tout le monde ici, c'est une optimisation prématurée.

Je ne vois pas comment fgets(tempfname[i], 20, fp); pourrait compiler, beaucoup moins de travail, puisque tempfname[i] est un string& et fgets nécessite un char*.

Probablement vous voulez

typedef char file_name[20]; // way too short 
file_name tempfnames[NUM_INPUT_FILES]; 

Bien que, parmi beaucoup d'autres changements que je ferais ici, vous pouvez tout gérer un fichier à chaque itération de boucle et éviter d'avoir un tableau de noms entièrement.