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 :

List of String Characters


Sujet :

C

  1. #1
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2016
    Messages : 11
    Par défaut List of String Characters
    Hello everyone,

    I'm new in C and would like to make a program which looks for all the files located in a given directory (with sub-directories) and stores the paths of the files inside a variable. My question is really simple, how can I create this kind of variable? I looked for that on many forums but they only explain how to store a single string characters. In my case, I can have up to 150000 string characters, one for each file. In Matlab, it's really simple, I will have for instance file_path{1} = 'C:\Test\art.mp3', file_path{2} = 'C:\Test\art_wave.mp3', etc... In other words, i would like to know how I can make a list of string characters in C.

    Thank you for your help,
    Andrew

  2. #2
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    Ça n'est pas si simple en langage C, il faut 2 niveaux d'allocation dynamiques. Un pour les chaines, un pour le tableau.
    Voilà une structure et 2 fonctions gérant les allocations et libérations.
    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
    struct ArrayOfStrings {
       char** dta;          // the string array itself
       unsigned nb;         // number of strings in it
       unsigned nbReserved; // current max string number
    };
     
    // allocate and return indice of the new inserted string
    int allocateANewString( const char* str , struct ArrayOfStrings* aos ) {
       if ( aos->nb >= aos->reserved ) { // not enough room, allocate for more
          unsigned moreReserve = (aos->nbReserved + 3) * 3 / 2;  // can reserve 50% more
          char** more = realloc( aos->dta , moreReserve*sizeof(char*) );
          if ( !more ) // not enough memory
             return -1;
          aos->dta = more;
          aos->nbReserved = moreReserve;
       }
       aos->dta[aos->nb] = malloc( strlen(str) + 1 ); // allocate for the string
       if ( !aos->dta[aos->nb] )
          return -1; // not enough memory
       strcpy( aos->dta[aos->nb] , str );
       return aos->nb++;
    }
     
    void deallocateAll( struct ArrayOfStrings* aos ) {
       if ( aos->dta ) {
          for ( int i = 0 ; i < aos->nb ; ++i )
             if ( aos->dta[i] )
                free( aos->dta[i] ); // free the strings
          free( aos->dta );          // free the array
       }
       aos->dta = NULL;
       aos->nbReserved = 0;
       aos->nb = 0;
    }
     
    int main() {
       struct ArrayOfStrings arrayOfStrings = {NULL,0,0};
     
       if ( 0<= allocateANewString( "first" , &arrayOfStrings ) )
          if ( 0<= allocateANewString( "second" , &arrayOfStrings ) )
             printf( "%s %s\n" , arrayOfStrings.dta[0] , arrayOfStrings.dta[1] );
     
       deallocateAll( &arrayOfStrings );
       return 0;
    }

  3. #3
    Membre Expert
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Par défaut
    Pour rebondir sur l'excellente proposition de dalfab, j'aime bien utiliser les VLA (/!\ C99+) dans ce genre de cas :

    Code strarray.h : 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
    #if !defined(INCL_STRARRAY_H)
      #define INCL_STRARRAY_H
     
     
    struct strarray {
        size_t capacity,
               size;
        char  *array[];
    };
     
     
    struct strarray *strarray_alloc();
    struct strarray *strarray_realloc(struct strarray *sa);
    int strarray_push(struct strarray **sa, char *s);
    void strarray_empty(struct strarray *sa);
    void strarray_free(struct strarray **sa);
    void strarray_fprint(FILE *stream, const struct strarray *sa);
     
     
    #endif // INCL_STRARRAY_H
    Code strarray.c : 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
    #include <stdio.h>
    #include <stdlib.h>
     
    #include "strarray.h"
     
     
    #define ALLOC_COUNT 3
     
    struct strarray *strarray_alloc() {
        struct strarray *sa = malloc(sizeof(struct strarray) + sizeof(char *) * ALLOC_COUNT);
     
        if (sa) {
            sa->capacity = ALLOC_COUNT;
            sa->size = 0;
        }
     
        return sa;
    }
     
    struct strarray *strarray_realloc(struct strarray *sa) {
        if (!sa)
            return strarray_alloc();
     
        struct strarray *sa_new = realloc(sa, sizeof(struct strarray) + sizeof(char *) * (sa->capacity + ALLOC_COUNT));
        if (sa_new)
            sa_new->capacity += ALLOC_COUNT;
     
        return sa_new;
    }
     
     
    int strarray_push(struct strarray **sa, char *s) {
        if ((*sa)->size == (*sa)->capacity) { // realloc if array is full
            struct strarray *sa_new = strarray_realloc(*sa);
            if (!sa_new)
                return -1;
     
            *sa = sa_new;
        }
     
        (*sa)->array[(*sa)->size] = s; // simply takes ownership, no copy
        return (*sa)->size++;
    }
     
    void strarray_empty(struct strarray *sa) {
        char **const array = sa->array;
     
        for (size_t i = 0; i < sa->size; ++i)
            free(array[i]);
     
        sa->size = 0;
    }
     
    void strarray_free(struct strarray **sa) {
        strarray_empty(*sa);
        free(*sa);
        *sa = NULL;
    }
     
    void strarray_fprint(FILE *stream, const struct strarray *sa) {
        char *const *const array = sa->array;
     
        size_t i = 0;
        for ( ; i < sa->size; ++i)
            fprintf(stream, "[%zu] -> '%s'\n", i, array[i]);
        for ( ; i < sa->capacity; ++i)
            fprintf(stream, "[%zu] -> (unused)\n", i);
    }
    Code main.c : 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
    #include <assert.h>
    #include <stdio.h>
    #include <string.h> // for strdup()
     
    #include "strarray.h"
     
     
    typedef struct strarray strarray_t;
     
     
    char *dup_and_check(const char *s) {
        char *copy = strdup(s);
        assert(copy && "allocation failure");
        return copy;
    }
     
    int main(int argc, char *argv[]) {
        strarray_t *sa = strarray_alloc();
        assert(sa && "allocation failure");
     
        int ret = strarray_push(&sa, dup_and_check("random string"));
        assert(ret == 0);
     
        strarray_fprint(stdout, sa);
        puts("");
     
        ret = strarray_push(&sa, dup_and_check("another one"));
        assert(ret == 1);
        ret = strarray_push(&sa, dup_and_check("this one is different"));
        assert(ret == 2);
     
        strarray_fprint(stdout, sa);
        puts("");
     
        ret = strarray_push(&sa, dup_and_check("what about that one?"));
        assert(ret == 3);
     
        strarray_fprint(stdout, sa);
        strarray_empty(sa);
        puts("\nstring array is now empty\n");
     
        ret = strarray_push(&sa, dup_and_check("we are finished"));
        assert(ret == 0);
     
        strarray_fprint(stdout, sa);
     
        strarray_free(&sa);
     
        assert(!sa && "something went really wrong here..");
        return 0;
    }

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ gcc -std=gnu11 -pedantic -Wall -Wextra main.c strarray.c
    $ ./a.out

    L'inconvénient est que la signature de certaines fonctions usuelles nécessite une indirection supplémentaire sur le paramètre de l'objet (car le tableau fait partie de la structure, il n'est pas alloué à part) : l'interface s'en trouve moins « clean ».

  4. #4
    Membre averti
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2016
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Août 2016
    Messages : 11
    Par défaut
    Merci dalfab et Matt_Houston pour vos réponses, vos propositions m'ont été très instructives. Il m'a fallu un petit temps pour les comprendre mais aujourd'hui c'est bon. Encore un immense merci

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

Discussions similaires

  1. récupérer la partie commune d'une liste de String
    Par Kanter dans le forum Delphi
    Réponses: 11
    Dernier message: 18/04/2007, 12h46
  2. Créer un tableau de liste de string
    Par nobeone dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 06/04/2007, 14h58
  3. Réponses: 23
    Dernier message: 08/06/2006, 15h06
  4. [VB.net] Join d'un Array list de string?
    Par the_bmo dans le forum VB.NET
    Réponses: 8
    Dernier message: 15/12/2005, 13h53
  5. Comparaison d'une liste de string à un string
    Par maxazac dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 19/10/2005, 15h39

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