IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

lecture d'un fichier txt


Sujet :

C

  1. #1
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut lecture d'un fichier txt
    Bjr
    j'essaye de lire un fichier txt sous la forme
    **** bienvenue****
    ****liste à afichier est la suivante*****
    Nom|said
    Prenom|samir
    age|22
    adresse|xxx
    ....

    le fichier peut contenir plusieurs lignes ça depend du nombre d'information de la personne.

    je veux en c avoir ces information dans un tableau de deux dimensions pour enregistrer que les information utiles (càd à partir de 3éme ligne)
    j'ai essayé de manipuler les fonctions fgets fgetc mais ça marche pas
    merci de m aider

  2. #2
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    Bonjour,

    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
     
    #include <stdio.h>
     
    # define MAX_LEN_LINE 1024 // Tu peux augmenter si tu veux
     
    int main()
    {
        char str[MAX_LEN_LINE];
        char **tab;
        FILE *file;
        int nbLine;
     
        nbLine = 0;
        if ((file = fopen("./dossier/fichier.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               return (-1); // Le fichier ne peut pas être lu ou n'existe pas
        while ((fgets(str, MAX_LEN_LINE, file))) // Compte le nombre de lignes à enregistrer dans le tableau
        {
           if (*str != '*') // Si la ligne ne commence pas par le symbole '*'
                nbLine++;
         }
        file = freopen("./dossier/fichier.txt", "r"); // Ferme et re-ouvre le fichier afin de placer le 'curseur' de lecture du fichier au début, ainsi fgets recommence à partir du début
        if ((tab = malloc(nbLine)) == NULL)
             return (1); // Si la mémoire demandée n'a pas pu être allouée
        nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file))) // On recommence la boucle pour relire les lignes du fichier
        {
            if ((tab[nbLine] = strdup(str)) == NULL) // Copie la ligne dans tab
                 return (-1); // Si la mémoire demandée n'a pas pu être allouée
            nbLine++;
        }
        fclose(file);
        return (0);
    }
    Je n'ai pas vérifier ce code, car je l'ai tapé directement dans le post mais je pense que ça devrait être bon. Si un point te semble obscure, n'hésite pas.
    A propos de fgets :
    Vérifie que tu as bien mis '#include <stdio.h>' et que tu as bien ouvert avec fopen(). Le prototype de fgets est => char *fgets (char *s, int size, FILE *stream);
    *s est une chaîne de caractère déjà allouée.
    size est le nombre de caractère lu au maximum. Cela évite des segmentations faults en écrivant dans s (si s[10] et que ta ligne fait 20 caractères, tu segfaulteras).
    FILE *stream est une variable particulière à utiliser avec les autres fonctions de même type comme fopen, fclose, fread, fwrite, fgets, fgetc etc.

  3. #3
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut lecture d'un fichier txt
    Merci bien mr hoder

    sinon votre programme ne veut pas être compiler
    c'est pour cela j'ai modifier file = freopen("./dossier/fichier.txt", "r"); // par fopen et maintenant ça marche.

    sinon pour afficher le tableau qui contient les ligne du fichier j'ai ajouter les lignes suivante a la fin de votre programme:
    for (i = 0; i< nbLine; i++)
    printf(" les lignes sont:\n", tab[i]);

    je pense que le tab[0] va contenir toute la ligne c'est a dire Nom|said
    moi j'ai besoin d'un tableau de deux dimensions
    par exemple tab[i][j] pour i=0 tab[i] = Nom
    et pour j=0 tab[j] = said


    merci bien pour vos effort



    Citation Envoyé par Hoder Voir le message
    Bonjour,

    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
     
    #include <stdio.h>
     
    # define MAX_LEN_LINE 1024 // Tu peux augmenter si tu veux
     
    int main()
    {
        char str[MAX_LEN_LINE];
        char **tab;
        FILE *file;
        int nbLine;
     
        nbLine = 0;
        if ((file = fopen("./dossier/fichier.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               return (-1); // Le fichier ne peut pas être lu ou n'existe pas
        while ((fgets(str, MAX_LEN_LINE, file))) // Compte le nombre de lignes à enregistrer dans le tableau
        {
           if (*str != '*') // Si la ligne ne commence pas par le symbole '*'
                nbLine++;
         }
        file = freopen("./dossier/fichier.txt", "r"); // Ferme et re-ouvre le fichier afin de placer le 'curseur' de lecture du fichier au début, ainsi fgets recommence à partir du début
        if ((tab = malloc(nbLine)) == NULL)
             return (1); // Si la mémoire demandée n'a pas pu être allouée
        nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file))) // On recommence la boucle pour relire les lignes du fichier
        {
            if ((tab[nbLine] = strdup(str)) == NULL) // Copie la ligne dans tab
                 return (-1); // Si la mémoire demandée n'a pas pu être allouée
            nbLine++;
        }
        fclose(file);
        return (0);
    }
    Je n'ai pas vérifier ce code, car je l'ai tapé directement dans le post mais je pense que ça devrait être bon. Si un point te semble obscure, n'hésite pas.
    A propos de fgets :
    Vérifie que tu as bien mis '#include <stdio.h>' et que tu as bien ouvert avec fopen(). Le prototype de fgets est => char *fgets (char *s, int size, FILE *stream);
    *s est une chaîne de caractère déjà allouée.
    size est le nombre de caractère lu au maximum. Cela évite des segmentations faults en écrivant dans s (si s[10] et que ta ligne fait 20 caractères, tu segfaulteras).
    FILE *stream est une variable particulière à utiliser avec les autres fonctions de même type comme fopen, fclose, fread, fwrite, fgets, fgetc etc.

  4. #4
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    c'est pour cela j'ai modifier file = freopen("./dossier/fichier.txt", "r"); // par fopen et maintenant ça marche.
    Oui, je suis allé un petit trop vite en effet, c'était
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    file = freopen("./dossier/fichier.txt", "r", file);
    par exemple tab[i][j] pour i=0 tab[i] = Nom
    et pour j=0 tab[j] = said
    Euh, j'ai pas bien compris là :s Tu n'aurais pas fait une erreur dans ta phrase ?
    tab[i] ou tab[j] dans les deux cas, c'est *tab.
    Peut-être veux-tu faire un tableau à trois dimensions type :
    char *tab[ligne][numeroInfo]
    Qui donnerait :
    tab[0][0] = "Nom"
    tab[0][1] = "said"
    tab[1][0] = "Prenom"
    tab[1][1] = "samir"
    ?

  5. #5
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    d'accord je pense que j'ai pas bien expliqué ce que je veux faire.
    mon tableau doit contenir
    chaque information utile dans une case du tableau (nom prenom age said samir adress..) pour apres je pourais faire des manipulations sur c'est données par exemple chercher si j ai un nom qui commense par 's' ou bien chercher si il ya un parametre age et voir si la valeurs correspondante >20
    comme si j'ai le tableau suivant

    Nom said
    Prenom Samir
    Age 22
    Nom fayiz

  6. #6
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    d'une autre façon

    si j 'ai le fichier

    ali : 24
    soufiane : 26
    said : 22
    amine : 25

    je veux enregister chaque nom avec son age correspondante
    apres cette operation l'utilisateur du programme va ecrire un nom et le programme va affichier l'age correspondante (si il la trouve sinon il va afficher que ce nom n'existe pas)

    j'espere que cette exemple va eclairssir ce que je veux faire.

  7. #7
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    #include <stdio.h>
     
    # define MAX_LEN_LINE	1024 // Tu peux augmenter si tu veux
    # define SEPARATOR		":" // Le separateur entre la variable et sa valeur dans le fichier texte
     
    char		**getData(char *line)
    {
    	int		len;
    	int		start_value;
    	char	**data;
     
    	// Allocation d'un double tableau
    	data = malloc(sizeof(**data) * 2); // 2 correspondant à la variable et sa valeur
     
    	// Récupération du nom de la variable dans data[0]
    	len = 0;
    	while (str[len] != '\0' && str[len] != SEPARATOR)
    		len++;
    	data[0] = malloc(len + 1));
    	len = 0;
    	while (str[len] != '\0' && str[len] != SEPARATOR)
    	{
    		data[0][len] = str[len];
    		len++;
    	}
    	data[0][len] = '\0';
     
    	// Récupération de la variable dans data[1]
    	start_value = ++len; // Sauvegarde l'emplacement du premier caractère suivant le séparateur
    	while (str[len] != '\0')
    		len++;
    	data[1] = malloc(len + 1);
    	while (str[start_value] != '\0')
    	{
    		data[1][start_value] = str[start_value];
    		start_value++;
    	}
    	data[1][start_value] = '\0';
    	return (data); // Avec donc data[0] = NomDeLaVariable
    					// Et data[1] = Variable, si les lignes se présentent sous la forme "NomDelaVariable:Variable"
    }
     
    int main()
    {
        char str[MAX_LEN_LINE];
        char **tab;
        FILE *file;
        int nbLine;
     
        nbLine = 0;
        if ((file = fopen("./dossier/fichier.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               return (-1); // Le fichier ne peut pas être lu ou n'existe pas
        while ((fgets(str, MAX_LEN_LINE, file))) // Compte le nombre de lignes à enregistrer dans le tableau
        {
           if (*str != '*') // Si la ligne ne commence pas par le symbole '*'
                nbLine++;
        }
        file = freopen("./dossier/fichier.txt", "r"); // Ferme et re-ouvre le fichier afin de placer le 'curseur' de lecture du fichier au début, ainsi fgets recommence à partir du début
        if ((tab = malloc(nbLine)) == NULL)
             return (1); // Si la mémoire demandée n'a pas pu être allouée
        nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file))) // On recommence la boucle pour relire les lignes du fichier
        {
    		if (*str != '*')
    		{
    			tab[nbLine] = getData(str);
    			nbLine++;
    		}
        }
        fclose(file);
        return (0);
    }
    Je n'ai pas vérifié le code une fois de plus donc il y a peut-être des erreurs, si ça ne marche pas, essaye de trouver les erreurs avec un debugger.

  8. #8
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    bonjour,

    merci bien hoder pour la reponse, effectivement j'ai trouver des erreurs de code mais je l ai rectifié et le programme est compilé sans problème.

    sincerement j'ai pas tout compris dans le code, et j'ai voulue voir au moins si ça marche et si il va donner ce que je veux. c'est pour cela j'ai ajouter ces deux lignes à la fin:
    for (i=0; i<nbLine; i++)
    printf("les valeurs sont: %c", tab[i]);

    mais voila ce qu il m affiche:

    les valeurs sont: ples valeurs sont: âles valeurs sont: 0les valeurs sont: E
    est ce que j utilise la bonne methode pour afficher mon tableau, vraiment je ne sais pas ou est le problème.

    merci bien

  9. #9
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    En effet, c'était bourré d'erreurs

    Voici un code fonctionnel, compilé avec g++ de QtCreator et testé sur le fichier texte suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Nom:Bernard
    Age:56
    Ville:Granville
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    # define MAX_LEN_LINE	1024 // Tu peux augmenter si tu veux
    # define SEPARATOR		':' // Le separateur entre la variable et sa valeur dans le fichier texte
     
    char		**getData(char *str)
    {
            int	len;
            int	start_value;
            char    **data;
     
            // Allocation d'un double tableau
            data = (char**)malloc(sizeof(**data) * 2); // 2 correspondant à la variable et sa valeur
     
            // Récupération du nom de la variable dans data[0]
            len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
                len++;
            data[0] = (char*)malloc(len + 1);
            len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
            {
                    data[0][len] = str[len];
                    len++;
            }
            data[0][len] = '\0';
     
            // Récupération de la variable dans data[1]
            start_value = ++len; // Sauvegarde l'emplacement du premier caractère suivant le séparateur
            while (str[len] != '\0')
                len++;
            data[1] = (char*)malloc(len + 1);
            len = 0;
            while (str[start_value] != '\0')
                data[1][len++] = str[start_value++];
            data[1][len] = '\0';
            return (data); // Avec donc data[0] = NomDeLaVariable
                                            // Et data[1] = Variable, si les lignes se présentent sous la forme "NomDelaVariable:Variable"
    }
     
    int main()
    {
        char str[MAX_LEN_LINE];
        char ***tab;
        FILE *file;
        int nbLine;
     
        nbLine = 0;
        if ((file = fopen("test.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               return (-1); // Le fichier ne peut pas être lu ou n'existe pas
        while ((fgets(str, MAX_LEN_LINE, file))) // Compte le nombre de lignes à enregistrer dans le tableau
        {
           if (*str != '*') // Si la ligne ne commence pas par le symbole '*'
                nbLine++;
        }
        file = freopen("test.txt", "r", file); // Ferme et re-ouvre le fichier afin de placer le 'curseur' de lecture du fichier au début, ainsi fgets recommence à partir du début
        if ((tab = (char***)malloc(nbLine)) == NULL)
             return (1); // Si la mémoire demandée n'a pas pu être allouée
        nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file))) // On recommence la boucle pour relire les lignes du fichier
        {
                    if (*str != '*')
                    {
                            tab[nbLine] = getData(str);
                            nbLine++;
                    }
        }
        tab[nbLine] = NULL;
        fclose(file);
        for (int i = 0 ; tab[i] != NULL ; i++)
            printf("%s : %s", tab[i][0], tab[i][1]);
        system("pause");
        return (0);
    }
    PS :
    for (i=0; i<nbLine; i++)
    printf("les valeurs sont: %c", tab[i]);
    Dans printf, %c affiche un caractère, or tu veux afficher une chaîne de caractère. Il faut donc utiliser %s (qui ne doit pas fonctionner dans l'horrible code que je t'ai donné dans mon post précédent)

  10. #10
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    Bonjour,

    merci bien votre code tourne bien et il repond à mes besoin, mais sincerement je l'ai pas bien compris, je pense que je dois lire de plus sur le langage c (les pointeurs,..)
    merci de m'envoyer des liens utiles sur ce sujet.
    apres je vais essayer de comprendre à nouveau votre programme et si j'aurai des difficultés je tiendrais au courant

    merci bien tu m as vraiment sauver

  11. #11
    Membre éclairé
    Inscrit en
    Avril 2010
    Messages
    66
    Détails du profil
    Informations personnelles :
    Âge : 34

    Informations forums :
    Inscription : Avril 2010
    Messages : 66
    Par défaut
    Pour débuter, je te conseille les cours de C et la FAQ C.
    Mais en attendant, je vais essayer de t'expliquer un maximum de chose en reprenant le code et en le découpant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int main()
    {
        char str[MAX_LEN_LINE];
        char ***tab;
        FILE *file;
        int nbLine;
     
        nbLine = 0;
        if ((file = fopen("test.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               return (-1); // Le fichier ne peut pas être lu ou n'existe pas
    La première chose qu'il faut faire avant de pouvoir traiter les données de ton fichier texte, il faut évidemment les récupérer. Pour cela on aurait pu utiliser la fonction read() mais la découpe ligne par ligne aurait été plus compliquée.
    On a donc utiliser fopen() pour d'abord ouvrir le fichier. On vérifie que l'ouverture du fichier a réussi en vérifiant la valeur renvoyée par fopen. Si une erreur est apparue, alors fopen() renvoie NULL (tu peux obtenir ce genre d'informations en tapant "man fopen" (ou plus généralement "man [nomDeLaFonction]" dans Google, premier lien, puis cherche "Valeur renvoyée" (ou tu peux le taper directement sur console si t'es sous Linux).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        while ((fgets(str, MAX_LEN_LINE, file)))
        {
           if (*str != '*')            
                  nbLine++;
        }
    fgets() récupère et stock dans 'str' chaque ligne du fichier. Une fois arrivé à la fin du fichier, fgets() renvoie NULL. Ainsi, le while(NULL) s'arrête. On aurait pu écrire plus clairement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while ((fgets(str, MAX_LEN_LINE, file)) != NULL)
    Grâce à cela, on a pu compter le nombre de lignes que l'on stockera dans un tableau. Car en C, il faut allouer la mémoire en indiquant la taille à malloc().

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
       file = freopen("test.txt", "r", file);
        if ((tab = (char***)malloc(nbLine)) == NULL)
             return (1);     nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file)))
        {
                    if (*str != '*')
                    {
                            tab[nbLine] = getData(str);
                            nbLine++;
                    }
        }
        tab[nbLine] = NULL;
        fclose(file);
    Ici, freopen() ferme et rouvre le fichier. Cela permet à fgets() de recommencer depuis le début (car étant arrivé à la fin du fichier dans la boucle précédente, fgets() renvoyait NULL).
    Suite à cela, on alloue un tableau. Pourquoi avoir choisi char*** ?
    Parce que l'on veut stocker des chaines de caractères (char*) dans un tableau (char**) de 2 cases (nomDeVariable et valeurDeLaVariable) et ce tableau correspondra à une case d'un autre tableau qui correspond au tableau des lignes (char***).
    En gros :
    char*** => Tableau de lignes
    char** => Tableau de 2 cases (contenant par exemple tab[0] = "Age", tab[1] = "25"
    char* => Chaîne de caractère, donc "Age" ou "25" selon la case demandée.
    Je suis pas sûr d'avoir été bien clair mais bon

    Ainsi, on recommence avec une boucle similaire à la boucle précédente lorsque l'on comptait le nombre de ligne, sauf que cette fois, on va pouvoir stocker les lignes dans ce tableau, et dont la dernière case sera différencié des autres par la "valeur" NULL. En gros, c'est pour connaître la fin du tableau.
    fclose() permet juste de fermer le fichier.

    A présent, voyons getData()
    Ici, on passe en paramètre une ligne du fichier, on a donc par exemple :
    str = "Nom:samir"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            data = (char**)malloc(sizeof(**data) * 2); // 2 correspondant à la variable et sa valeur
    Comme on veut un tableau de deux cases qui contiendront respectivement le nom de la variable et sa valeur sous forme de chaîne de caractères, on déclare un char** que l'on alloue de 2 cases.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
         // Récupération du nom de la variable dans data[0]
            len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
                len++;
    Ici, on "parse" la ligne. On va chercher dans str, grâce à len l'endroit où se trouve le SEPARATOR (ici ':'). Une fois qu'on l'aura trouvé, on connaîtra la taille de la mémoire à allouée. Pour reprendre avec l'exemple de tout à l'heure :
    str = "Nom:samir"
    On va parser avec len :
    len = 0 => str[len] = 'N';
    len = 1 => str[len] = 'o';
    len = 2 => str[len] = 'm';
    len = 3 => str[len] = ':';
    len vaudra donc 3.
    Ainsi, il nous fait allouer une chaîne de caractère de 3 octets pour la première case de notre tableau en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    data[0] = (char*)malloc(len + 1);
    (D'ailleurs, je remarque que j'ai alloué une case mémoire en trop)
    Normalement, il faudrait valider la valeur de retour, c'est juste que j'avais la flemme.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
            {
                    data[0][len] = str[len];
                    len++;
            }
            data[0][len] = '\0';
    Puis de nouveau on recommence la boucle mais cette fois, on enregistre dans data[0]. Tu noteras qu'en fait, c'est le même principe depuis le début :
    on cherche la taille de ce que l'on va allouée, on alloue, on refait la même chose mais en enregistrant cette fois. Et c'est exactement ce qu'on va refaire, sauf que cette fois, len ne commence pas au début mais au ':', soit len = 3. Une fois la boucle termine, on clôt la chaîne de caractère avec un '\0'.
    ++len signifie que l'on incrémente len (qu'on ajoute 1) avant d'exécuter l'instruction. On sauvegarde la position de len pour que, lors de l'étape de l'enregistrement, on sache où recommencer (c'est-à-dire à 's' dans "Nom:samir").
    Donc rebelotte, on recherche la taille, on alloue, on refait l'opération en enregistrant, puis on return pour envoyer notre double tableau.

    Comme ceci, on place un char** dans une case du char***. En gros, char*** englobe des char** qui englobent des char*.

    Voilà, j'espère que toutes ces explications t'auront servis.

  12. #12
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    Bonjour Mr horder, désolé de ne pas vous repondre. j'ai commencé à lire les cours et tutoriels C et il m a permis de comprendre beaucoup de chose. et vraiment vos explication m'ont beaucoup servis.

    merci bien sinon j'ai une autre question:
    est ce qu il y a une methode dans Cpour que mon programme(devellopé en C) ecoute l'execution d'un morceau de code qui appartient à un autre programme developé en C ou C++ ou bien java.

    cette question je vais la déposer dans un autre titre du forums mais je voulais comme même vous poser la question.

    merci bien

  13. #13
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    bonjour

    je programme precedent marche tres tres bien sous windows en utilisant comme IDE code::blocks
    mais je voulais migres sous linux mais malheureusement le programme ne marche pas malgres que j'utilise le même IDE (version linux)

    j'ai cette erreur:
    ***glibc detected***/test/bin/debug/test: corrrupted double-linked list: 0x09bf4168***

  14. #14
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    j'ai testé le code ligne par ligne et apparent l'erreur devient de la ligne fclose(file)
    parceque quand je la mets en commentaire le programme tourne bien sans erreur
    mais pour afficher les nom avec les ages correspondant on doit commencer la boucle de i=1 sinon (i=0)j'ai une ligne bizzard du genre hx 2x 2 .. je sais pas ce que ça veut dire

    merci de m'aider à comprendre ce qui se passe

  15. #15
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    La discussion devient difficile à suivre, car le code est dispersé sur plusieurs post et on ne sait plus très bien quel code tu utilises.

    Je pense qu'il serait utile de récapituler la situation en postant le code que tu utilises actuellement ce qui permettra de réfléchir sur des données sûres.

  16. #16
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    Bonjour,

    le programme précédent marche bien actuellement sous windows et sous linux
    ce programme stock les données (sépparé par d'un fichier dans un tableau de 2 cases

    Actuellement j'ai un fichier qui contient plus d'information càd
    ali : 24 :50
    soufiane : 26 : 60
    said : 22 : 25
    amine : 25 : 40

    donc j'ai besoin de stocker ce fichier dans un tableau à trois cases

    j'ai déclarrer plus de memoire et pour tab*** j'ai fais tab****

    mais malheureusement ça marche pas

    merci pour vos aides

  17. #17
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Comme l'a dit quelqu'un juste au-dessus, redonne ton code (celui qui fonctionne).
    Et tant qu'à faire, donne aussi le code modifié qui ne fonctionne pas.

    Comme cela, on pourra y voir plus clair, et pointer les éléments qui ne vont pas.

  18. #18
    Membre actif
    Inscrit en
    Mars 2009
    Messages
    47
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 47
    Par défaut
    voila le code qui marche et qui remplie un tableau de 2 cases
    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    #include <iostream>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
     
    # define MAX_LEN_LINE	1024 // Tu peux augmenter si tu veux
    # define SEPARATOR		':' // Le separateur entre la variable et sa valeur dans le fichier texte
     
    char		**getData(char *str)
    {
            int	len;
            int	start_value;
            char    **data;
     
            // Allocation d'un double tableau
            data = (char**)malloc(sizeof(**data) * 2); // 2 correspondant à la variable et sa valeur
     
            // Récupération du nom de la variable dans data[0]
            len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
                len++;
            data[0] = (char*)malloc(len + 1);
            len = 0;
            while (str[len] != '\0' && str[len] != SEPARATOR)
            {
                    data[0][len] = str[len];
                    len++;
            }
            data[0][len] = '\0';
     
            // Récupération de la variable dans data[1]
            start_value = ++len; // Sauvegarde l'emplacement du premier caractère suivant le séparateur
            while (str[len] != '\0')
                len++;
            data[1] = (char*)malloc(len + 1);
            len = 0;
            while (str[start_value] != '\0')
                data[1][len++] = str[start_value++];
            data[1][len] = '\0';
            return (data); // Avec donc data[0] = NomDeLaVariable
                                            // Et data[1] = Variable, si les lignes se présentent sous la forme "NomDelaVariable:Variable"
    }
     
    int main()
    {
        char str[MAX_LEN_LINE];
        char ***tab;
        FILE *file;
        int nbLine;
        int i;
     
        nbLine = 0;
        if ((file = fopen("/home/test.txt", "r")) == NULL) // Ouvre le fichier ciblé à "./dossier/fichier.txt' en mode lecture (r comme read)
               {
                   return (-1); // Le fichier ne peut pas être lu ou n'existe pas
                   printf("le fichier n'existe pas");
               }
     
        while ((fgets(str, MAX_LEN_LINE, file))) // Compte le nombre de lignes à enregistrer dans le tableau
        {
           if (*str != '*') // Si la ligne ne commence pas par le symbole '*'
                nbLine++;
     
        }
     
      file = freopen("/home/test.txt", "r", file); // Ferme et re-ouvre le fichier afin de placer le 'curseur' de lecture du fichier au début, ainsi fgets recommence à partir du début
     
        if ((tab = (char***)malloc(nbLine)) == NULL)
     
        return (1); // Si la mémoire demandée n'a pas pu être allouée
     
     
     nbLine = 0;
        while ((fgets(str, MAX_LEN_LINE, file))) // On recommence la boucle pour relire les lignes du fichier
        {
                    if (*str != '*')
                    {
                            tab[nbLine] = getData(str);
                            nbLine++;
     
                    }
     
        }
     
     
       tab[nbLine] = NULL;
       //fclose(file);
           for (i = 1; tab[i] != NULL ; i++)
           printf("%s : %s", tab[i][0], tab[i][1]);
     
       // system("pause");
     
        return (0);
    }
    le code qui marche pas c'est la meme chose en modifiant juste tab*** par tab****
    puisque ça marchait pas je l'ai pas enregistrer

  19. #19
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    C'est sûr que si tu contentes de remplacer « char ***tab » par « char ****tab », ça ne va pas pas marcher du tout.
    Changer le type d'une variable a des répercussions partout où elle est susceptible d'être utilisée.
    Il faut donc faire très attention.

    Mais comme tu le dis toi-même, tu as besoin d'utiliser un « tableau à trois cases » au lieu d'un « tableau de deux cases ».
    Autrement dit, tu veux rajouter une case pour chaque ligne, donc rajouter une colonne à ton tableau.

    Or, ce que tu fais, c'est rajouter une dimension.
    Ce n'est pas du tout la même chose !
    Cherche bien, ce n'est pas ici que tu dois rajouter « une couche ».
    Il y a un autre endroit où un « deux » doit se transformer en « trois »…

    Si tu ne vois pas, demande-toi bien comment sont formés les tableaux (à deux dimensions) en C, et ce que cela implique de rajouter une colonne (ou une case par ligne).
    La solution te paraîtra alors évidente.

  20. #20
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Il y a une erreur dans ton code "qui marche" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            char    **data;
     
            // Allocation d'un double tableau
            data = (char**)malloc(sizeof(**data) * 2);
    ce code alloue 2 char ( type de **data) et non pas deux char * :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
         data = malloc(2 * sizeof *data);
    D'autre part, il y a de grandes similitudes entre le code qui crée et construit data[0] et celui utilisé pour data[1]. Il y a intérêt, surtout si tu passes à plus de données, à grouper ces codes en écrivant une fonction utilisable pour data[0], data[1],...

Discussions similaires

  1. lecture d'un fichier txt ligne par ligne
    Par SoBaKa dans le forum Général Python
    Réponses: 4
    Dernier message: 06/03/2007, 12h02
  2. Lecture depuis un fichiers txt
    Par mask91 dans le forum C++
    Réponses: 15
    Dernier message: 04/03/2007, 22h40
  3. Réponses: 4
    Dernier message: 13/11/2006, 22h30
  4. Lecture et ecriture fichier txt
    Par jeanmy dans le forum Delphi
    Réponses: 12
    Dernier message: 07/08/2006, 17h23
  5. [debutant] lecture d'un fichier txt de 10mo
    Par karamazov994 dans le forum Entrée/Sortie
    Réponses: 11
    Dernier message: 19/04/2005, 15h55

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo