Je voudrais savoir si vous connaissiez une petite méthode pour connaitre le nombre de ligne dans un fichier texte, meme avec une commande systeme
Je voudrais savoir si vous connaissiez une petite méthode pour connaitre le nombre de ligne dans un fichier texte, meme avec une commande systeme
Vive le C => Quoique pas sympa pour la mémoire de mon PC.
Seul le chat le savait!!!!
De la rigueur en programmation est maître mot!!!
Il existe bien des commandes systèmes, mais ca dépénd du système !
S'il n'y a pas de solution, c'est qu'il n'y a pas de problème
Il doit pouvoir fonctionner sous Window et Unix.
Etre tres rapide.
Vive le C => Quoique pas sympa pour la mémoire de mon PC.
Seul le chat le savait!!!!
De la rigueur en programmation est maître mot!!!
Utiliser fgets alors... Ou alors, utiliser des #ifdef pour savoir sous quel OS tu te trouves et utiliser wc sous unix par exemple...Envoyé par theshark85
Jc
Sous unix :Sous windows, je ne sais pas. En installant cygwin, tu as la même commande que ci-dessus.
Code : Sélectionner tout - Visualiser dans une fenêtre à part wc -l
Software Failure. Press left mouse button to continue.Guru Meditation #0100000C.000FE800
Ceci doit etre portable, donc pas de possibilité d'installer des biblio ou autres.
Avec fgets entre 2 et 3 minutes pour 11 100 000 lignes. Qui dit mieux!!!
Vive le C => Quoique pas sympa pour la mémoire de mon PC.
Seul le chat le savait!!!!
De la rigueur en programmation est maître mot!!!
Voici une fonction que j'ai y'a un ptit moment maintenant, je pense qu'elle peut être optimisé, a voir !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 int c_file_nb_lines (char const * const s_filename) { FILE * p_file = NULL; char * s_line = NULL; int nb_lines = 0; /* ----- Ouverture du fichier ----- */ p_file = fopen (s_filename, "r"); if (!p_file) { /* Erreur: impossible d'ouvrir le fichier. */ return -1; } /* ----- */ /* ----- Allocation d'un tableau pour contenir la ligne ----- */ s_line = malloc (MAX_LENGHT); if (!s_line) { /* Erreur: impossible d'allouer l'espace requis. */ fclose (p_file); return -1; } /* ----- */ /* ----- Lecture de la ligne du fichier ----- */ while (fgets (s_line, MAX_LENGHT, p_file)) { memset (s_line, 0, sizeof (s_line)); nb_lines++; } if (ferror (p_file)) { /* Erreur pendant la lecture du fichier. */ return -1; } /* ----- */ /* ----- Fermeture du fichier ----- */ fclose (p_file); /* ----- */ return nb_lines; }
Mon Site
Ma bibliothèque de gestion des chaînes de caractères en C
L'imagination est plus importante que le savoir. A. Einstein
Je ne répond à aucune question technique par MP, merci d'avance !
Merci pour vos réponses, j'ai garde la méthode gets, car du coup je fai un autre truc en meme temps.
Vive le C => Quoique pas sympa pour la mémoire de mon PC.
Seul le chat le savait!!!!
De la rigueur en programmation est maître mot!!!
Il manque free(s_line);
D'ailleurs pourquoi une alloc dynamique pour une taille dependante d'un #define (je suppose).
Introduction à Silverlight 4 (new) ; Localisation d'une application Silverlight (new) ;
Mon espace perso[/B]
La connaissance s’acquiert par l’expérience, tout le reste n’est que de l’information. Albert Einstein[/SIZE]
Hum oui c'est juste, c'est super rare que j'oublie un free, fallais que ca tombe sur cette fonction ! Oui tu suppose bien, m'enfin je me rappel même plus quand j'ai fait cette fonction !Envoyé par Skyrunner
Vais changer ca
Mon Site
Ma bibliothèque de gestion des chaînes de caractères en C
L'imagination est plus importante que le savoir. A. Einstein
Je ne répond à aucune question technique par MP, merci d'avance !
Bon si jamais ca interesse encore theshark85
code modifié:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 int c_file_nb_lines (char const * const s_filename) { FILE * p_file = NULL; char s_line [MAX_LENGHT]; int nb_lines = 0; /* ----- Ouverture du fichier ----- */ p_file = fopen (s_filename, "r"); if (!p_file) { /* Erreur: impossible d'ouvrir le fichier. */ return -1; } /* ----- */ /* ----- Lecture de la ligne du fichier ----- */ while (fgets (s_line, MAX_LENGHT, p_file)) { nb_lines++; } if (ferror (p_file)) { /* Erreur pendant la lecture du fichier. */ fclose (p_file); return -1; } /* ----- */ /* ----- Fermeture du fichier ----- */ fclose (p_file); /* ----- */ return nb_lines; }
Mon Site
Ma bibliothèque de gestion des chaînes de caractères en C
L'imagination est plus importante que le savoir. A. Einstein
Je ne répond à aucune question technique par MP, merci d'avance !
Aller un challenge...Envoyé par theshark85
Voici comment j'ai créé le fichier test:
En créant un fichier de 50 meg, j'ai:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #include <stdio.h> #include <time.h> int main(int argc, char **argv) { int size,i; int cnt=0; srand(time(NULL)); if(argc!=2) { printf("Error dans la ligne de commande\n"); return 1; } printf("Creating file size\n"); size= strtol(argv[1],NULL,0); printf("Creating file size: %d\n",size); FILE *f = fopen("filetotest","w"); if(f==NULL) { printf("Error\n"); return 1; } for(i=0;i<size;i++) { if(rand()%500>350) {cnt++;fprintf(f,"\n");} else fprintf(f,"_"); } printf("Created %d lines\n",cnt); fclose(f); }
En utilisant ce programme:~/tmp$ ./createf 50000000
Creating file size
Creating file size: 50000000
Created 14894826 lines
J'obtiens:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <stdlib.h> #include <stdio.h> #define N 4096 int main(int argc, char **argv) { char buf[N]; int i,size; int cnt=0; if(argc!=2) return 1; FILE *f = fopen(argv[1],"r"); if(f==NULL) return 1; while((size=fread(buf,1,N,f))>0) { for(i=0;i<size;i++) { if(buf[i]=='\n') cnt++; } } fclose(f); printf("Lignes: %d\n",cnt); return 0; }
Donc, je dis mieux...~/tmp$ time ./a.out filetotest
Lignes: 14894826
real 0m0.152s
user 0m0.120s
sys 0m0.027s
Jc
Ta fonction a un problème...Envoyé par CSoldier
Tu ne connais pas la taille maximale de la ligne. Tu supposes que c'est MAX_LENGTH mais ce n'est pas forcément si "petit"...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 while (fgets (s_line, MAX_LENGHT, p_file)) { memset (s_line, 0, sizeof (s_line)); nb_lines++; }
Il faudrait tester si le dernier caractère de ta chaîne s_line est bien un '\n' avant d'incrémenter...
Ensuite, je ne vois pas l'intérêt du memset... A la prochaine lecture, le début de la chaîne sera écrasé et il y aura un '\0' pour ne pas déborder sur les anciennes valeurs...
Jc
Salut,
Il faudrait qu'il essaie sur la même machine pour voir quel code est plus rapide !
Il serait encore plus rapide d'avoir une ligne d'enregistrement de longueur fixe, et de faire un simple calcul sur la taille du fichier; je dis ça, car apparement tu es soucieux de la rapidité, et ça peut être une optimisation interessante pour ton programme
A+
K
Est-ce que vous croyez que ça vaut vraiment le coup d'optimiser ce genre de routine, sachant qu'on est limité par le temps d'accès du média ?
Software Failure. Press left mouse button to continue.Guru Meditation #0100000C.000FE800
La version de CSoldier utilisant fgets:Envoyé par KiLVaiDeN
time ./a.out filetotest
Lignes: 14894827
real 0m2.440s
user 0m2.359s
sys 0m0.024sDépendant de l'importance qu'a le facteur temps et le nombre de fois où il faudra appeler la fonction avoir le choix entre .2 seconde et 2.4 secondes, je sais ce que je préfère...Est-ce que vous croyez que ça vaut vraiment le coup d'optimiser ce genre de routine, sachant qu'on est limité par le temps d'accès du média ?
En plus, il faudrait rajouter un strlen pour être vraiment sûr du nombre de lignes dans la version de CSoldier...
Mais dans la réalité, les deux méthodes sont bonnes et acceptables, je faisais simplement remarquer qu'il y avait plus rapide en réponse à la phrase:
Avec fgets entre 2 et 3 minutes pour 11 100 000 lignes. Qui dit mieux!!!
Jc
Hum ouaipe effectivement, moi je cherche jamais directement à optimiser étant donné qu'on n'est pas spécialement a 1 ou 2 secondes prés et que cela dépend aussi du media mais c'est une bonne chose que de tester différentes versions
Mon Site
Ma bibliothèque de gestion des chaînes de caractères en C
L'imagination est plus importante que le savoir. A. Einstein
Je ne répond à aucune question technique par MP, merci d'avance !
En général, je pense qu'il est toujours interessant d'optimiser un traitement quand ce dernier est destiné à être souvent appellé. Car un petit cycle de CPU économisé, lors d'un milllion d'itérations, ça commence à faire beaucoup de petits cycles
Après, si il ne s'agit que d'un traitement ponctuel, l'optimisation est secondaire selon moi et il vaut mieux se concentrer sur la gestion de la mémoire, enfin c'est ce que j'en dis, les experts ont peut-être un avis différent sur la question !
En l'occurence, le temps de réponse du média est grandement supérieur à l'économie faite lors d'une quelconque optimisation; donc l'optimisation devient négligeable je dirais, comme tu fais bien de le souligner !
K
On a bien dit compter les lignes ? Pourquoi les charger ? Il suffit de compter les délimiteurs...Envoyé par theshark85
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include<stdio.h> #define fname "fichier.txt" int main() { FILE *fp = fopen(fname, "r"); if (fp != NULL) { unsigned long count = 0; int c; while ((c = fgetc(fp)) != EOF) { if (c == '\n') { count++; } } fclose(fp); printf("%lu lines\n", count); } else { perror(fname); } return 0; }
Pas de Wi-Fi à la maison : CPL
Je suis d'accord que ce n'est pas la peine de les charger mais :
Vu que je me suis mis en position d'arbitre entre les versions:
Donc pour le moment tu es plus lent Emmanuel. Peut-être parce que je lis en bloc de 4096 caractères? Mais je pense plutôt que c'est parce que tu va faire 4096 fois plus d'appels que moi.... Ca ça détruit la vitesse de ton code...time ./compteemmanuel
14894826 lines
real 0m0.950s
user 0m0.908s
sys 0m0.035s
En utilisation mémoire par contre, tu gagnes...
Still champion,
Jc
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager