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 :

Allocation de mémoire dynamique et tableaux


Sujet :

C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut Allocation de mémoire dynamique et tableaux
    Bonjour,

    Je suis en train d'essayer coder une fonction qui puisse chercher un fichier dans un dossier donné en fonction de son nom, indiqué pour la recherche.

    Par exemple, si dans un dossier, j'ai les 3 fichiers .txt suivants :

    ROUSSEAU.txt
    BAUDELAIRE.txt
    HUGO.txt

    Je voudrais que la fonction puisse me dire si ROUSSEAU.txt existe sans avoir recours à fopen().

    Voilà où j'en suis :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
     
    /* But : Tester l'existence d'un fichier donné dans un répertoire. */
     
    int CHERCHE(char chaine[]);
     
    char NOMA[] = "ROUSSEAU";
    int EXIST = -1;
     
    int main()
    {
        CHERCHE(NOMA);
        printf("\nEXIST = %d", EXIST);
    }
     
    int CHERCHE(char chaine[])
    {
        char SEARCH_PATH[] = "C:\\Sauvegarde_B\\Fichiers_txt\\*.txt";
        char A[20]; /* buffer */
        char *NOMA_CHECK = NULL;
     
        int EXIST = -1;
        int a;
        int x;
     
        WIN32_FIND_DATA File;
        HANDLE hSearch;
     
        hSearch = FindFirstFile(SEARCH_PATH, &File);
        if (hSearch != INVALID_HANDLE_VALUE)
        {
            do
            {
                strcpy(A, File.cFileName);
                for (a = 0; a < sizeof((A)-1); a++)
                {
                    while (A[a] != '.') /* Je parse le contenu de File.cFileName afin d'obtenir le nom du fichier sans son extension */
                    {
                        fputc(A[a], stdout);
                        a++;
                    }
                    a += 1; /* J'augmente a de 1 afin de réserver un octet pour le caractère \0 null de fin de chaîne */
                    printf("\n%d", a); /* Ici a représente en réalité la taille de la chaîne qui doit être stockée dans NOMA_CHECK en octets de chaque chaîne de caractères */
     
                    if (NULL == (NOMA_CHECK = malloc((sizeof(char))*a)))
                    {
                        printf("\Erreur d'allocation de mémoire.");
                    }
                    else
                    {
                        fgets(NOMA_CHECK, sizeof(NOMA_CHECK), stdout); /* On récupère le contenu de stdout et on le stocke dans NOMA_CHECK : normalement, NOMA_CHECK fait pil poile la taille de la chaîne qu'il contient, du moins c'est ce que je cherche à faire et je n'y arrive pas, ça ne marche pas. */
                        if ((x = strcmp(NOMA_CHECK, chaine)) == NULL) /* Comparaison des deux chaînes */
                        {
                            EXIST = 1; /* Si les chaînes sont identiques, EXIST vaut 1 et on sort de la fonction car le fichier a été trouvé */
                            return(EXIST);
                        }
                        printf("\n%d", sizeof(NOMA_CHECK)); /* Je vérifie si la taille du tableau correspond bien à celle allouée par malloc() : et c'est la le problème, ça ne corresond pas, ça me renvoie toujours 4 et je ne comprends pas */
                        printf("\n");
                    }
                    fflush(stdout);
                    fflush(stdin);
                    free(NOMA_CHECK);
                    free(A);
                    /* On vide de tout caractère les différents flots et tableaux utilisés après avoir travailler sur chaque fichier */
                }
            } while (FindNextFile(hSearch, &File));
            FindClose(hSearch);
        }
        EXIST = 0; /* Aucun fichier portant le nom de la chaîne recherchée n'a été trouvé : EXIST renvoie 0 */
        return(EXIST);
    }
    J'ai commenté au mieux le code pour que vous puissiez m'aider plus facilement.

    En fait, je ne comprends pas pourquoi je n'arrive pas à allouer dynamiquement mon tableau NOMA_CHECK à chaque fois. Il vaut toujours 4 alors qu'il contient des chaînes de caractères qui peuvent aller de 3 lettres à plus de 20...

    Soit il y a un souci dans mon code (je suis sur ce problème depuis plus de 5h), soit je n'ai pas compris le fonctionnement de l'allocation dynamique de mémoire et auquel cas je voudrais bien quelques explications.

    Merci par avance !

    Merillym.

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    "sizeof de tableau" ne marche pas sur les pointeurs; seulement sur les variables ayant un vrai type tableau[taille].
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    "sizeof de tableau" ne marche pas sur les pointeurs; seulement sur les variables ayant un vrai type tableau[taille].
    Donc du coup, je présume que l'allocation se fait correctement ? Ou qu'elle ne se fait pas ? Dès lors comment faire ?

    Dès lors, je ne comprends pas pourquoi ma fonction me renvoie toujours -1, et jamais 1 ou 0.

    Normalement, si les deux chaînes NOMA_CHECK et NOMA sont identiques, la strcmp() devrait renvoyer 0.

    Je vais continuer à chercher, mais si vous avez des idées, je suis preneur.


  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Si malloc() n'a pas retourné NULL, l'allocation s'est faite correctement. Mais tu passes un mauvais paramètre de taille à fgets().

    Et aussi, je ne suis pas sûr que a soit le bon argument à passer à malloc()...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Si malloc() n'a pas retourné NULL, l'allocation s'est faite correctement. Mais tu passes un mauvais paramètre de taille à fgets().

    Et aussi, je ne suis pas sûr que a soit le bon argument à passer à malloc()...
    Pourtant, la variable a représente bien le nombre d'octets qu'il me faut au moment où j'appelle malloc(), je l'ai vérifié avec un printf().

    J'ai essayé de mettre un nombre, mettons 15, pour la taille, ça ne marche pas mieux ( c'était juste pour tester ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                    if (NULL == (NOMA_CHECK = malloc((sizeof(char))*15)))
                    {
                        printf("\Erreur d'allocation de mémoire.");
                    }
                    else
                    {
                        fgets(NOMA_CHECK, 15, stdout);
    Le problème, c'est que NOMA_CHECK ne se remplit pas avec le contenu de stdout. J'ai déjà mieux cerné le problème, mais je ne vois pas où ça coince.

    J'ai aussi vérifié le contenu de stdout, il se remplit bien à chaque fois.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par Merillym Voir le message
    Pourtant, la variable a représente bien le nombre d'octets qu'il me faut au moment où j'appelle malloc(), je l'ai vérifié avec un printf().

    J'ai essayé de mettre un nombre, mettons 15, pour la taille, ça ne marche pas mieux ( c'était juste pour tester ).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                    if (NULL == (NOMA_CHECK = malloc((sizeof(char))*15)))
                    {
                        printf("\Erreur d'allocation de mémoire.");
                    }
                    else
                    {
                        fgets(NOMA_CHECK, 15, stdout);
    Le problème, c'est que NOMA_CHECK ne se remplit pas avec le contenu de stdout. J'ai déjà mieux cerné le problème, mais je ne vois pas où ça coince.

    J'ai aussi vérifié le contenu de stdout, il se remplit bien à chaque fois.
    Je crois avoir trouvé

    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
    for (a = 0; a < sizeof((A)-1); a++)
                {
                    while (A[a] != '.')
                    {
                        a++;
                    }
                    a++;
                    printf("\nA : %d", a);
                    if ((NOMA_CHECK = malloc(a)) != NULL )
                    {
                        printf("\nAllocation mémoire réussie !");
                    }
                    else
                    {
                        printf("\Echec !");
                    }
                    for (b = 0; b < sizeof((A)-1); b++)
                    {
                        while (A[b] != '.')
                        {
                            NOMA_CHECK[b] = A[b];
                            b++;
                            if (A[b] == '.')
                            {
                                NOMA_CHECK[b] = '\0';
                            }
                        }
                    }
                    printf("\n%s", NOMA_CHECK);
    Là, NOMA_CHECK est toujours bien rempli.

    Par contre, j'ai un problème avec strcmp. Faut que je règle ça.

    Merci pour tes indications Médinoc, ça m'a aidé à trouver ce qui n'allait pas

    Je te tiens au courant pour la suite.

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Mon grain de sel: Sépare ton code un peu mieux en fonctions.
    N'hésite pas à utiliser (ou si tu n'en as pas le droit, reproduire) les fonctions de <string.h>: strchr(), strlen(), le strdup() de POSIX...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    J'apprends le C en autodidacte, je fais ça sur mon temps libre.

    J'ai justement du mal à séparer mon code en fonction, car j'ai dû mal à cerner quand est-ce que je peux faire une fonction etc.

    Je suis preneur de tout conseil.


  9. #9
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Merillym Voir le message
    Le problème, c'est que NOMA_CHECK ne se remplit pas avec le contenu de stdout.
    stdout est la sortie standard de l'application, pas l'entrée (qui est stdin). C'est un flux en écriture pas en lecture, donc tu ne peux pas le lire (au passage que cherchais-tu à faire exactement ?)

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2009
    Messages
    140
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2009
    Messages : 140
    Points : 49
    Points
    49
    Par défaut
    Citation Envoyé par gl Voir le message
    stdout est la sortie standard de l'application, pas l'entrée (qui est stdin). C'est un flux en écriture pas en lecture, donc tu ne peux pas le lire (au passage que cherchais-tu à faire exactement ?)
    Grâce aux indication de Médinoc, j'ai pu trouver, je vous mets donc le code complet de la fonction que je vais intégrer dans le programme que je suis en train de faire afin de m'entraîner.

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <windows.h>
     
    /* But : Tester l'existence d'un fichier donné dans un répertoire. */
     
    int CHERCHE(char ch[]);
     
    char NOMA[] = "ROUSSEAU";
     
    int main()
    {
        if (CHERCHE(NOMA) == 1)
        {
            printf("\nFichier trouvé !");
        }
        else
        {
            printf("\nFichier non trouvé !");
        }
    }
     
    int CHERCHE(char ch[])
    {
        char SEARCH_PATH[] = "C:\\Sauvegarde_B\\Fichiers_txt\\*.txt";
        char A[20]; /* buffer */
        char *NOMA_CHECK = NULL;
        int a, b;
        int x;
     
        WIN32_FIND_DATA File;
        HANDLE hSearch;
     
        hSearch = FindFirstFile(SEARCH_PATH, &File);
        if (hSearch != INVALID_HANDLE_VALUE)
        {
            do
            {
                strcpy(A, File.cFileName);
                for (a = 0; a < sizeof((A)-1); a++)
                {
                    while (A[a] != '.')
                    {
                        a++;
                    }
                    a++;
                    printf("\nA : %d", a);
                    if ((NOMA_CHECK = malloc(a)) != NULL )
                    {
                        printf("\nAllocation mémoire réussie !");
                    }
                    else
                    {
                        printf("\Echec !");
                    }
                    for (b = 0; b < sizeof((A)-1); b++)
                    {
                        while (A[b] != '.')
                        {
                            NOMA_CHECK[b] = A[b];
                            b++;
                            if (A[b] == '.')
                            {
                                NOMA_CHECK[b] = '\0';
                            }
                        }
                    }
                    printf("\n%s", NOMA_CHECK);
                    printf("\n%s\n", ch);
     
                    if ((x = strcmp(NOMA_CHECK, ch)) == NULL)
                    {
                        return 1;
                    }
     
                    char *NOMA_CHECK = NULL;
                    fflush(stdout);
                    free(A);
                }
            } while (FindNextFile(hSearch, &File));
            FindClose(hSearch);
        }
        return 0;
    }
    Concernant cette ligne : if ((x = strcmp(NOMA_CHECK, ch)) == NULL)

    Pourquoi le compilateur me renvoie le warning suivant : comparison between pointer and integer ?

    La fonction marche bien mais je ne comprends pas pourquoi j'ai un tel warning.

    Le but de la fonction est de parcourir tous les fichiers d'un répertoire pour tester l'existence d'un fichier, dont le nom a été fourni en argument à la fonction. Je ne voulais pas utiliser fopen() pour le faire, car c'était aussi un moyen de m'entraîner.

    Après, je peux faire en sorte que ma fonction puisse rechercher n'importe quel fichier donné sur le PC, mais je n'en ai pas besoin pour le moment.

    J'espère que j'ai été clair

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par Merillym Voir le message
    Concernant cette ligne : if ((x = strcmp(NOMA_CHECK, ch)) == NULL)

    Pourquoi le compilateur me renvoie le warning suivant : comparison between pointer and integer ?
    La variable x (et le retour de strcmp()) est un entier, pas un pointeur, donc il ne faut pas utiliser NULL mais 0.

    La norme prévoit que NULL puisse être défini comme valant 0 ou (void*)0.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/03/2012, 06h56
  2. allocation dynamique et tableaux de pointeurs
    Par gbardy dans le forum 4D
    Réponses: 3
    Dernier message: 06/07/2006, 11h08
  3. Allocation et réallocation dynamique de tableaux
    Par petitmic dans le forum C++
    Réponses: 4
    Dernier message: 14/03/2006, 14h59
  4. [debutant] : Allocation de mémoire dynamique
    Par sam.fet dans le forum Langage
    Réponses: 5
    Dernier message: 15/02/2006, 14h58
  5. Allocation mémoire dynamique
    Par ITISAR dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 21/01/2005, 09h59

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