Obtenir nbre element depuis fichier

Fermé
hadrienlearn - Modifié le 5 févr. 2022 à 23:50
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 - 8 févr. 2022 à 15:53
Bonjour,
Je poste ce message car j'ai un problème que je ne vois pas comment résoudre.
J'essaye de développer un petit outil de répertoire téléphonique qui sauvegarde les donnée dans un fichier save.data.
Lors de son lancement mon programme récupère les donnée du fichier et les intégre dans un tableau qui sera ensuite utiliser dans les différent fonction de mon programme.
contenue du fichier :
Hadrien 12313215 
Laurent 12321321 
Helory 1231231 


ma structure:
typedef struct person
{
 char name[MAX_NAME_CHAR];
 char tel[MAX_TEL_CHAR];
}pers;


J'ai besoin de developper une fonction qui me permetterai de savoir combien de profil(nom + tel) se trouve dans mon fichier afin d'adapter le nombre d'element dans mon tableau de profile utilisé. Bien entendu mon programme doit pouvoir s'adapter a un fichier de donnée dynamique (+ ou - de profile etc.).
Je remercie d'avance les gens qui me fourniront de l'aide bonne journée


Configuration: Windows / Chrome 97.0.4692.99
A voir également:

2 réponses

Dalfab Messages postés 706 Date d'inscription dimanche 7 février 2016 Statut Membre Dernière intervention 2 novembre 2023 101
6 févr. 2022 à 09:44
Bonjour,

Le nombre de profils est le nombre de lignes de ton fichier. Le nombre de lignes peut aussi être le nombre de retour à la ligne dans ton fichier mais imposerait que tous les nom+tel soient suivis d'un retour à la ligne y compris le dernier et qu'il n'y aie aucune ligne vide.
Le seul moyen de faire cela est de lire le fichier pour compter ces lignes.
Mais comme lire un fichier est une opération lente, peut-être est-il plus judicieux d'en profiter pour récupérer dynamiquement les nom+tel.
1
mamiemando Messages postés 33372 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 22 novembre 2024 7 802
Modifié le 8 févr. 2022 à 16:06
Bonjour,

Comme le dit fort justement DalFab, avant d'avoir lu le fichier, tu ne peux pas connaître le nombre de profil à charger, d'autant que pour une allocation statique, cela signifierait que tu es capable de répondre à cette question à la compilation, pas à l'exécution. C'est le cas par exemple pour un numéro de téléphone (tu sais qu'il ne peut en aucun cas excéder un certain nombre de chiffre), mais pas pour la taille du répertoire. Ça pourrait être le cas pour le nom d'un contact (quitte à ce que ton programme interdise des saisies de nom trop long). Mais à moins que ton programme limite le nombre de profils et interrompe la lecture du fichier si cette borne est atteinte, ce n'est pas le cas pour le nombre de profils.

Cela signifie que tu devras faire l'allocation dynamiquement (e.g. avec
malloc
).Une structure adaptée pour être une liste chaînée, pour laquelle tu alloues un nouveau maillon à chaque fois que tu découvres un nouveau profil au cours de la lecture du fichier contenant le répertoire. Tu pourrais aussi imaginer utiliser un tableau quitte à utiliser
realloc
pour augmenter sa taille si sa capacité est insuffisante.

Ensuite comme le dit également fort justement, il faut idéalement ne faire qu'une seule passe sur ton fichier d'entrée. Le code sera plus élégant, plus court et plus performant.

Tu peux t'inspirer de ce code, qui charge une liste chaînée de chaîne de caractère à partir d'un fichier.

Attention car ce code reste incomplet car
strdup
alloue de la mémoire (et donc tout
strdup
doit avoir été libéré avec
free
avant la fin du programme). Il en va de même pour tout ce qui a été alloué avec
malloc
ou
calloc
. De plus, il faudrait contrôler que le fichier est ouvert avec succès. Bref après correction, voici à quoi ça ressemble :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct list {
    char *string;
    struct list *next;
};

typedef struct list LIST;

int main(void) {
    FILE * fp;
    char line[128];
    LIST * current, * head;
    const char * filename = "test.txt";
    fp = fopen(filename, "r");

    if (fp) {
        // Load list
        head = current = NULL;
        while (fgets(line, sizeof(line), fp)) {
            LIST *node = malloc(sizeof(LIST));
            node->string = strdup(line);
            node->next = NULL;

            if (!head) {
                current = head = node;
            } else {
                current = current->next = node;
            }
        }
        fclose(fp);
    } else {
        fprintf(stderr, "Can't read %s\n", filename);
        return 1;
    }


    // Test print
    for (current = head; current; current = current->next) {
        printf("%s", current->string);
    }

    // Need free for each node
    for (current = head; current;) {
        free(current->string);
        LIST * current_old = current;
        current = current->next;
        free(current_old);
    }
    return 0;
}


Dans ton cas il faut bien entendu adapter
struct list
de sorte à contenir un
struct pers
(ou directement ses attributs, à savoir le nom et le numéro de téléphone) :

Bonne chance
0