2009-08-04 10 views
3

Quelle est la méthode la plus compacte pour calculer le nombre de lignes d'un fichier? J'ai besoin de cette information pour créer/initialiser une structure de données matricielle.Méthode la plus compacte pour compter le nombre de lignes dans un fichier en C++

Plus tard, je dois à nouveau parcourir le fichier et stocker les informations dans une matrice.

Mise à jour: Basé sur Dave Gamble. Mais pourquoi cela ne compile pas? Notez que le fichier peut être très volumineux. J'essaie donc d'éviter d'utiliser le conteneur pour économiser de la mémoire.

#include <iostream>  
#include <vector>   
#include <fstream>  
#include <sstream>  
using namespace std;  


int main (int arg_count, char *arg_vec[]) { 
    if (arg_count !=2) { 
     cerr << "expected one argument" << endl; 
     return EXIT_FAILURE;  
    } 

    string line; 
    ifstream myfile (arg_vec[1]); 

    FILE *f=fopen(myfile,"rb"); 
    int c=0,b; 
    while ((b=fgetc(f))!=EOF) c+=(b==10)?1:0; 
    fseek(f,0,SEEK_SET); 


    return 0; 
} 
+0

vous nous dire pourquoi il ne peut pas compiler. Publiez vos erreurs de compilation. – GManNickG

+1

La supposition, cependant, est que vous devez '#include ' – GManNickG

+2

FICHIER * f = fopen (arg_vec [1], "rb"); S'il vous plaît. –

Répondre

6
FILE *f=fopen(filename,"rb"); 

int c=0,b;while ((b=fgetc(f))!=EOF) c+=(b==10)?1:0;fseek(f,0,SEEK_SET); 

Réponse dans c. Ce genre de compact?

+0

Ew. [Blah blah 15 caractères] – GManNickG

+2

Soyez reconnaissant je suis parti dans le? 1: 0. Cela fonctionne bien sans. J'ai pu enregistrer 4 caractères là;) –

+4

'int c = 0; while (! Fscanf (f,"% * [^ \ n]% * c ")) C++; fseek (f, 0, SEEK_SET)' –

1

Comptez le nombre d'instances de '\n'. Cela fonctionne pour les terminaisons de ligne * nix (\ n) et DOS/Windows (\ r \ n), mais pas pour le Mac old-skool (Système 9 ou peut-être avant cela), qui utilisait simplement \ r. Je n'ai jamais vu un cas arriver avec seulement des fins de ligne, donc je ne m'inquiéterais pas à moins que vous sachiez que ça va être un problème. Editer: Si votre saisie n'est pas ASCII, vous pouvez également rencontrer des problèmes d'encodage. À quoi ressemble votre contribution?

+0

Cela pourrait ne pas être multi-plateforme (je dis juste). – Kredns

+0

@ 280Z28: Comment faites-vous cela? – neversaint

10

Si la raison pour laquelle vous devez "revenir en arrière" est parce que vous ne pouvez pas continuer sans la taille, essayez de réorganiser votre configuration. C'est-à-dire, lire le fichier, stocker chaque ligne dans un std::vector<string> ou quelque chose. Ensuite, vous avez la taille, ainsi que les lignes du fichier:

#include <fstream> 
#include <iostream> 
#include <string> 
#include <vector> 

int main(void) 
{ 
    std::fstream file("main.cpp"); 
    std::vector<std::string> fileData; 

    // read in each line 
    std::string dummy; 
    while (getline(file, dummy)) 
    { 
     fileData.push_back(dummy); 
    } 

    // and size is available, along with the file 
    // being in memory (faster than hard drive) 
    size_t fileLines = fileData.size(); 

    std::cout << "Number of lines: " << fileLines << std::endl; 
} 

Voici une solution sans le contenant:

#include <fstream> 
#include <iostream> 
#include <string> 
#include <vector> 

int main(void) 
{ 
    std::fstream file("main.cpp"); 
    size_t fileLines = 0;  

    // read in each line 
    std::string dummy; 
    while (getline(file, dummy)) 
    { 
     ++fileLines; 
    } 

    std::cout << "Number of lines: " << fileLines << std::endl; 
} 

Bien que je doute que ce soit la façon la plus efficace. L'avantage de cette méthode était la possibilité de stocker les lignes en mémoire au fur et à mesure.

+0

C'est la méthode que j'allais suggérer, mais cela fait assez longtemps que j'ai utilisé le C++ que j'allais devoir tester avant de poster. Merci de m'avoir fait gagner du temps + 1: D –

+3

Je + VRAIMENT + aime quand je peux dire que quelqu'un a réellement testé le code, en vertu du fait que le nom du fichier source est là en entrée: D: D –

+0

lol, ouais. J'ai eu ce 'bingo'! moment où je pensais, "j'ai besoin d'un fichier pour tester avec .... oh duh" – GManNickG

10

Je pense que cela pourrait le faire ...

std::ifstream file(f); 
int n = std::count(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), '\n') + 1; 
+0

+1 pour savoir comment utiliser streambufs. – quark

3
#include <stdlib.h> 
int main(void) { system("wc -l plainfile.txt"); }