En C, chaines de caractères dans un fichier
r2
-
fiddy Messages postés 11653 Statut Contributeur -
fiddy Messages postés 11653 Statut Contributeur -
Bonjour,
J'aurais aimé créer un programme qui puisse savoir si le contenu d'un répertoire a changé et si oui, me donner le nom des fichiers. J'ai deux fichier rep et rep.old. En utilisant stdio.h je veux pouvoir enregistrer les noms de fichiers dans 2 tableaux (de pointeurs), un qui donne la liste de rep et l'autre de rep.old. Mon problème c'est que je n'arrive à rien avec fscanf, je débute en C et les pointeurs et les chaines de caractères c'est vraiment galère :( Quand j'essaye ca, ca m'affiche (null);
/* le fichiers sont déja ouverts*/
int cmp-rep ( ) {
char *liste[80], *liste_old[80];
fscanf ( fichier, "%s", liste[1] );
printf ("%s", liste[1] );
}
pour l'instant, je voudrais "prendre" seulement le premier nom qui apparait dans le fichier
j'aimerai savoir ce qui va pas, pourriez vous me proposer une fonction qui marcherait ?
Merci d'avance
PS : Les fichiers ont comme contenu :
fichier1
fichier2
fichier....
J'aurais aimé créer un programme qui puisse savoir si le contenu d'un répertoire a changé et si oui, me donner le nom des fichiers. J'ai deux fichier rep et rep.old. En utilisant stdio.h je veux pouvoir enregistrer les noms de fichiers dans 2 tableaux (de pointeurs), un qui donne la liste de rep et l'autre de rep.old. Mon problème c'est que je n'arrive à rien avec fscanf, je débute en C et les pointeurs et les chaines de caractères c'est vraiment galère :( Quand j'essaye ca, ca m'affiche (null);
/* le fichiers sont déja ouverts*/
int cmp-rep ( ) {
char *liste[80], *liste_old[80];
fscanf ( fichier, "%s", liste[1] );
printf ("%s", liste[1] );
}
pour l'instant, je voudrais "prendre" seulement le premier nom qui apparait dans le fichier
j'aimerai savoir ce qui va pas, pourriez vous me proposer une fonction qui marcherait ?
Merci d'avance
PS : Les fichiers ont comme contenu :
fichier1
fichier2
fichier....
A voir également:
- En C, chaines de caractères dans un fichier
- Fichier bin - Guide
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier rar - Guide
- Fichier .dat - Guide
4 réponses
Bonjour,
Lorsque vous faites
liste[0] est un pointeur auquel il faut lui donné une adresse ! ( l'adresse d'un char ou d'un tableau de char [ou de tout type en fait, le type char* est aussi utilisé pour éviter de faire des calculs sur les adresses lorsqu'on utilise le type void* qui sert pour stocker les adresses de type différents] )
exemple :
Vous voyez s[0] récupère l'adresse de la chaîne "a" et s[1] celle de "b"
Pour lire un fichier utilisez fread avec une boucle,
exemple :
Lorsque vous faites
char *liste[80]ça créer un tableau de 80 pointeurs de type char, autrement dit :
liste[0] est un pointeur auquel il faut lui donné une adresse ! ( l'adresse d'un char ou d'un tableau de char [ou de tout type en fait, le type char* est aussi utilisé pour éviter de faire des calculs sur les adresses lorsqu'on utilise le type void* qui sert pour stocker les adresses de type différents] )
exemple :
#include <stdio.h>
int main(void)
{
char *s[2];
char *a="hello world";
char *b="bonjour tout le monde";
s[0]=a;
s[1]=b;
printf("%s\n",s[0]);
printf("%s\n",s[1]);
return 0;
}
Vous voyez s[0] récupère l'adresse de la chaîne "a" et s[1] celle de "b"
Pour lire un fichier utilisez fread avec une boucle,
exemple :
#include <stdio.h>
int main(void)
{
char buffer[10];
size_t count,i;
FILE *fichier;
fichier = fopen("test.txt","r");
if(fichier)
{
while((count=fread(buffer,sizeof(char),10,fichier))){
for(i=0;i<count;i++)
printf("%c",buffer[i]);
}
}
fclose(fichier);
return 0;
}
J'ai essayé ce que tu m'as proposé, ca marche mais j'obtiens tout ce qui est dans le fichier dans une seule chaine de caractères, sauf que ce que je voudrais faire c'est enregistrer ma liste de noms dans un tableau (de pointeurs ?) selon un motif genre "%s" en employant fscanf.
J'ai essayé ce que tu m'as proposé, ca marche mais j'obtiens tout ce qui est dans le fichier dans une seule chaine de caractères, sauf que ce que je voudrais faire c'est enregistrer ma liste de noms dans un tableau (de pointeurs ?) selon un motif genre "%s" en employant fscanf.
ci dessous le programme que j'essaye de faire :
#define VRAI 0
#define T 128
FILE *fichier, *fichier_old;
int comp_file (void) {
char text[T];
char *liste[T], *liste_old[T];
int n= 0 , i, j;
printf ("Comparaison avec l'ancienne liste ... \n");
/* Mettre les noms dans le tableau liste */
while ( fscanf ( fichier, "%s", text ) != EOF )
{
liste[n] = text;
printf ( "%s\n", liste[n] ); // Test pour voir ce qu'il y a dans liste[n]
n ++;
}
i=n; //i indique le nombre d'elements dans liste
printf ( "Le repertoire de maintenant contient %d élements:\n", i );
/* Afficher les éléménts */
printf ("%s\n", liste[0] );
printf ("%s\n", liste[1] );
n=0; //réinitialise n
/* Mettre les noms dans le tableau liste_old */
while ( fscanf ( fichier_old, "%s", text) != EOF )
{ liste_old[n] = text; n++; }
j=n; // j indique le nombre d'elements dans liste_old
/* Afficher les élements */
printf ("Le répertoire d'avant contenait %d élements : \n", j );
for ( n=0; n<=j; n++ )
{ printf ("%s\n", liste_old[n] ); }
return (0);
}
Mon probleme c'est que la premiere boucle affiche la liste avec printf mais quand je veux "revoir" la liste, ca ecrit la derniere chaine de caractere du fichier :( J'aimerai savoir mon erreur svp.
#define VRAI 0
#define T 128
FILE *fichier, *fichier_old;
int comp_file (void) {
char text[T];
char *liste[T], *liste_old[T];
int n= 0 , i, j;
printf ("Comparaison avec l'ancienne liste ... \n");
/* Mettre les noms dans le tableau liste */
while ( fscanf ( fichier, "%s", text ) != EOF )
{
liste[n] = text;
printf ( "%s\n", liste[n] ); // Test pour voir ce qu'il y a dans liste[n]
n ++;
}
i=n; //i indique le nombre d'elements dans liste
printf ( "Le repertoire de maintenant contient %d élements:\n", i );
/* Afficher les éléménts */
printf ("%s\n", liste[0] );
printf ("%s\n", liste[1] );
n=0; //réinitialise n
/* Mettre les noms dans le tableau liste_old */
while ( fscanf ( fichier_old, "%s", text) != EOF )
{ liste_old[n] = text; n++; }
j=n; // j indique le nombre d'elements dans liste_old
/* Afficher les élements */
printf ("Le répertoire d'avant contenait %d élements : \n", j );
for ( n=0; n<=j; n++ )
{ printf ("%s\n", liste_old[n] ); }
return (0);
}
Mon probleme c'est que la premiere boucle affiche la liste avec printf mais quand je veux "revoir" la liste, ca ecrit la derniere chaine de caractere du fichier :( J'aimerai savoir mon erreur svp.
Selon moi, plutôt que fread, tu devrais utiliser la fonction getline (qui te renvoie toute une ligne de ton fichier sous la forme de char *, à chaque appelle, ça te donne la ligne d'après)
Tu auras plus de facilité pour enregistrer chaque nom dans une case de ton tableau de pointeurs (et comme le nombre de lignes du fichier est inconnu, il faudra ré allouer ce tableau de pointeur à chaque fois, pour ça, je t'oriente vers la fonction realloc).
ça donnerait en gros un
Réfère toi aux manuels pour la syntaxe exacte des arguments (que je n'ai plus en tête)
edit :
J'oubliais quelque chose d'important, pour la lecture d'un tableau il est généralement assez délicat d'utiliser une variable contenant la taille de ce tableau. Ici, le dernier appelle à getline mettra NULL à la derniere case de ton tableau, donc pour en lire le contenu, la boucle sera plus simple à reproduire n'importe ou dans le code sans devoir garder une variable qui garderait sa taille :
J'espère ne pas m'être trompé dans ce que tu voulais faire ;)
Tu auras plus de facilité pour enregistrer chaque nom dans une case de ton tableau de pointeurs (et comme le nombre de lignes du fichier est inconnu, il faudra ré allouer ce tableau de pointeur à chaque fois, pour ça, je t'oriente vers la fonction realloc).
ça donnerait en gros un
int i = 0;
while ((tab[i++] = getline(arguments)) != NULL)
{
tab = realloc(taille actuelle + 1);
}
Réfère toi aux manuels pour la syntaxe exacte des arguments (que je n'ai plus en tête)
edit :
J'oubliais quelque chose d'important, pour la lecture d'un tableau il est généralement assez délicat d'utiliser une variable contenant la taille de ce tableau. Ici, le dernier appelle à getline mettra NULL à la derniere case de ton tableau, donc pour en lire le contenu, la boucle sera plus simple à reproduire n'importe ou dans le code sans devoir garder une variable qui garderait sa taille :
int i = 0;
while (tab[i] != NULL)
{
printf("%s\n", tab[i++]);
}
J'espère ne pas m'être trompé dans ce que tu voulais faire ;)
Dsl pour mon temps de réponse, les vacances...
Merci pour vos infos :) je vais pouvoir essayer de me débrouiller avec tout ça, dans mon coin j'avais réussi en utilisant aussi struct mais sans pointeur, ca m'a evité les erreurs de segmentation, mais les pointeurs ont l'air vraiment incontournable alors je vais y travailler de ce pas... encore merci ;)
Merci pour vos infos :) je vais pouvoir essayer de me débrouiller avec tout ça, dans mon coin j'avais réussi en utilisant aussi struct mais sans pointeur, ca m'a evité les erreurs de segmentation, mais les pointeurs ont l'air vraiment incontournable alors je vais y travailler de ce pas... encore merci ;)
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #define SZBUF 4096 /* pour le buff utilisé dans fread */ #define SZLTMP 65536 /* pour le buff temporaire servant à stocker une ligne (taille max d'une ligne lu) */ typedef struct{ char **tabptr; /* tableau qui stock les lignes */ unsigned int n; /* nombre de lignes en stock */ }fline2tab; void free_fline2tab(fline2tab *ft) { unsigned int i; for(i=0;i<ft->n;i++) free(ft->tabptr[i]); free(ft->tabptr); free(ft); } fline2tab *get_file_lines(const char *path) { char buffer[SZBUF], *temp=NULL, **tabptrtmp; size_t count,i; int z=0; FILE *file; fline2tab *ft; file = fopen(path,"r"); if(!file) return NULL; temp=malloc(sizeof(char)*(SZLTMP+1)); if(!temp){ fclose(file); return NULL; } ft=malloc(sizeof(fline2tab)); if(!ft){ fclose(file); free(temp); return NULL; } ft->tabptr=NULL; ft->n=0; while((count=fread(buffer,sizeof(char),SZBUF,file))){ for(i=0;i<count;i++){ if((z<SZLTMP) && buffer[i]!='\n' && buffer[i]!='\r'){ temp[z]=buffer[i]; z++; } if((buffer[i]=='\n' || (i==count-1 && count<SZBUF)) && z>0) { temp[z]='\0'; tabptrtmp=realloc(ft->tabptr,sizeof(char*)*(ft->n+1)); assert(tabptrtmp); ft->tabptr=tabptrtmp; ft->tabptr[ft->n]=malloc(sizeof(char)*(z+1)); memcpy(ft->tabptr[ft->n],temp,z+1); ft->n+=1; z=0; } } } free(temp); fclose(file); return ft; } /* ************************** */ void print_tab(char **tab,unsigned int n) { unsigned int i; for(i=0;i<n;i++) printf("%d - %s\n",i,tab[i]); } int main(void) { fline2tab *ft; ft=get_file_lines("test.txt"); /* lit et stock chaque ligne du fichier dans ft */ print_tab(ft->tabptr,ft->n); /* affichage */ free_fline2tab(ft); /* libère la mémoire utilisé par ft */ return EXIT_SUCCESS; }il n'y a plus qu'à utiliser le type "fline2tab" pour stocker les lignes en utilisant la fonction get_file_lines puis de libérer la mémoire quand on en a plus besoin.. prend en charge les fichier texte avec sauts de ligne du type \r\n , \n\r et \n