Comment créer un tableau de chaînes en C?

j'essaie de créer un tableau de chaînes en C. Si j'utilise ce code:

char (*a[2])[14];
a[0]="blah";
a[1]="hmm";

gcc me donne "avertissement: l'affectation d'incompatible pointer type". Quelle est la bonne façon de le faire?

edit: je suis curieux de savoir pourquoi cela devrait donner un avertissement de compilateur puisque si je fais printf(a[1]); , il imprime correctement "hmm".

211
demandé sur K48 2009-07-06 22:47:03

14 réponses

si vous ne voulez pas changer les chaînes, alors vous pouvez simplement faire

const char *a[2];
a[0] = "blah";
a[1] = "hmm";

quand vous le faites comme ceci, vous attribuerez un tableau de deux pointeurs à const char . Ces pointeurs seront alors positionnés sur les adresses des chaînes statiques "blah" et "hmm" .

si vous voulez être en mesure de changer le contenu réel de la chaîne, vous devez faire quelque chose comme

char a[2][14];
strcpy(a[0], "blah");
strcpy(a[1], "hmm");

deux tableaux consécutifs de 14 char s chacun, après quoi le contenu des chaînes statiques sera copié dans eux.

183
répondu Mikael Auno 2013-01-23 12:53:38

il y a plusieurs façons de créer un tableau de chaînes en C. Si toutes les chaînes vont avoir la même longueur (ou au moins la même longueur maximale), vous déclarez simplement un tableau 2-d de char et assignez comme nécessaire:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1];
...
strcpy(strs[0], aString); // where aString is either an array or pointer to char
strcpy(strs[1], "foo");

vous pouvez ajouter une liste d'initialisateurs aussi bien:

char strs[NUMBER_OF_STRINGS][STRING_LENGTH+1] = {"foo", "bar", "bletch", ...};

cela suppose que la taille et le nombre de chaînes dans l'initialiseur correspondent à vos dimensions de tableau. Dans ce cas, le contenu de chaque la chaîne de caractères littérale (qui est elle-même un tableau à fin zéro de char) est copiée dans la mémoire attribuée à strs. Le problème avec cette approche est la possibilité de fragmentation interne; si vous avez 99 chaînes qui sont 5 caractères ou moins, mais 1 chaîne qui est 20 caractères de long, 99 chaînes vont avoir au moins 15 caractères inutilisés; c'est une perte d'espace.

au lieu d'utiliser un tableau 2-d de char, vous pouvez stocker un tableau 1-d de pointeurs à char:

char *strs[NUMBER_OF_STRINGS];

notez que dans ce cas, vous n'avez attribué de mémoire que pour tenir les pointeurs vers les chaînes; la mémoire des chaînes elles-mêmes doit être attribuée ailleurs (soit sous forme de tableaux statiques, soit en utilisant malloc() ou calloc()). Vous pouvez utiliser la liste d'initialiseur comme l'exemple précédent:

char *strs[NUMBER_OF_STRINGS] = {"foo", "bar", "bletch", ...};

au lieu de copier le contenu des constantes de chaîne, vous stockez simplement les pointeurs vers elles. Notez que les constantes de chaîne peut ne pas être accessible en écriture; vous peut réattribuer le pointeur, comme cela:

strs[i] = "bar";
strs[i] = "foo"; 

mais vous ne pouvez pas changer le contenu de la chaîne; i.e.,

strs[i] = "bar";
strcpy(strs[i], "foo");

ne peut pas être admis.

vous pouvez utiliser malloc() pour affecter dynamiquement le buffer pour chaque chaîne et le copier dans ce buffer:

strs[i] = malloc(strlen("foo") + 1);
strcpy(strs[i], "foo");

BTW,

char (*a[2])[14];

, Déclare un 2 de l'élément de tableau de pointeurs vers 14-élément des tableaux de char.

147
répondu John Bode 2014-04-14 23:40:59

Ack! Cordes constantes:

const char *strings[] = {"one","two","three"};

si je me souviens bien.

Oh, et si vous voulez utiliser strcpy pour l'affectation, et non pas l'opérateur=. strcpy_s est plus sûre, mais ce n'est ni en C89, ni en C99 normes.

char arr[MAX_NUMBER_STRINGS][MAX_STRING_SIZE]; 
strcpy(arr[0], "blah");

mise à Jour: Thomas dit strlcpy est le chemin à parcourir.

74
répondu mpen 2016-12-19 18:23:01

ou vous pouvez déclarer un type de structure, qui contient un caractère arry (1 chaîne), ils créent un tableau des structures et donc un tableau multi-éléments

typedef struct name
{
   char name[100]; // 100 character array
}name;

main()
{
   name yourString[10]; // 10 strings
   printf("Enter something\n:);
   scanf("%s",yourString[0].name);
   scanf("%s",yourString[1].name);
   // maybe put a for loop and a few print ststements to simplify code
   // this is just for example 
 }

l'Un des avantages de ce sur toute autre méthode est que cela vous permet de numériser directement dans la chaîne sans avoir à utiliser strcpy ;

11
répondu FutureSci 2018-06-30 02:29:39

in ANSI C:

char* strings[3];
strings[0] = "foo";
strings[1] = "bar";
strings[2] = "baz";
10
répondu Noldorin 2009-07-06 18:50:58

voici quelques-unes de vos options:

char a1[][14] = { "blah", "hmm" };
char* a2[] = { "blah", "hmm" };
char (*a3[])[] = { &"blah", &"hmm" };  // only since you brought up the syntax -

printf(a1[0]); // prints blah
printf(a2[0]); // prints blah
printf(*a3[0]); // prints blah

l'avantage de a2 est que vous pouvez alors faire ce qui suit avec des cordes littérales

a2[0] = "hmm";
a2[1] = "blah";

et pour a3 vous pouvez faire ce qui suit:

a3[0] = &"hmm";
a3[1] = &"blah";

pour a1, vous devrez utiliser strcpy même lorsque vous assignez des chaînes de caractères littérales. La raison est que a2, et a3 sont des tableaux de pointeurs et vous pouvez faire leurs éléments (i.e. pointeurs) pointer vers n'importe quel stockage, tandis que a1 est un tableau de 'tableau de caractères' et donc chaque élément est un tableau qui "possède" son propre stockage (ce qui signifie qu'il est détruit quand il sort de la portée) - vous ne pouvez copier que des choses dans son stockage.

cela nous amène également à l'inconvénient d'utiliser a2 et a3 - car ils pointent vers le stockage statique (où les chaînes de caractères sont stockées) dont le contenu ne peut pas être modifié de manière fiable (à savoir. comportement non défini), si vous voulez assigner des littérales non-string aux éléments de a2 ou a3 - vous devrez tout d'abord allouer suffisamment de mémoire dynamiquement et ensuite avoir leurs éléments pointés vers cette mémoire, puis copier les caractères dans elle - et ensuite vous devez être sûr de désallouer la mémoire une fois fait.

Bah me manque C++ déjà ;)

p. S. Faites-moi savoir si vous avez besoin d'exemples.

10
répondu Faisal Vali 2009-07-07 04:36:21

Les littéraux de chaîne sont const char * .

et votre utilisation de la parenthèse est étrange. Vous voulez probablement dire

const char *a[2] = {"blah", "hmm"};

qui déclare un tableau de deux pointeurs vers des caractères constants, et les initialise pour pointer vers deux constantes de chaîne codées en dur.

6
répondu dmckee 2009-07-06 18:49:30

Si les chaînes sont statiques, ce que vous faites le mieux: "les 151920920"

const char *my_array[] = {"eenie","meenie","miney"};

bien que ne faisant pas partie de l'anse de base, il y a des chances que votre environnement supporte la syntaxe. Ces chaînes sont immuables (en lecture seule), et par conséquent dans de nombreux environnements utilisent moins de overhead que la construction dynamique d'un tableau de chaînes.

par exemple dans les petits projets de micro-contrôleur, cette syntaxe utilise la mémoire de programme plutôt que (habituellement) la mémoire ram plus précieuse. AVR-C en est un exemple environnement l'appui de cette syntaxe, mais la plupart des autres.

6
répondu Bryce 2014-07-25 19:24:33

si vous ne voulez pas garder la trace du nombre de chaînes dans le tableau et que vous voulez itérer dessus, ajoutez juste la chaîne nulle à la fin:

char *strings[]={ "one", "two", "three", NULL };

int i=0;
while(strings[i]) {
  printf("%s\n", strings[i]);
  //do something
  i++;
};
5
répondu Sergey 2017-04-06 08:49:50

votre code crée un tableau de pointeurs de fonction. Essayez

char* a[size];

ou

char a[size1][size2];

à la place.

voir wikibooks à tableaux et pointeurs

3
répondu Dario 2009-07-06 18:53:15
char name[10][10]
int i,j,n;//here "n" is number of enteries
printf("\nEnter size of array = ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
    for(j=0;j<1;j++)
    {
        printf("\nEnter name = ");
        scanf("%s",&name[i]);
    }
}
//printing the data
for(i=0;i<n;i++)
{
    for(j=0;j<1;j++)
    {
        printf("%d\t|\t%s\t|\t%s",rollno[i][j],name[i],sex[i]);
    }
    printf("\n");
}

essayez ça!!!

0
répondu Aditya 2014-09-05 15:13:23

il me manquait en quelque sorte un tableau plus dynamique de chaînes, où la quantité de chaînes pouvait varier en fonction de la sélection de l'exécution, mais autrement les chaînes devaient être corrigées.

j'ai fini de code comme ceci:

#define INIT_STRING_ARRAY(...)          \
    {                                   \
        char* args[] = __VA_ARGS__;     \
        ev = args;                      \
        count = _countof(args);         \
    }

void InitEnumIfAny(String& key, CMFCPropertyGridProperty* item)
{
    USES_CONVERSION;
    char** ev = nullptr;
    int count = 0;

    if( key.Compare("horizontal_alignment") )
        INIT_STRING_ARRAY( { "top", "bottom" } )

    if (key.Compare("boolean"))
        INIT_STRING_ARRAY( { "yes", "no" } )

    if( ev == nullptr )
        return;

    for( int i = 0; i < count; i++)
        item->AddOption(A2T(ev[i]));

    item->AllowEdit(FALSE);
}

char** ev capte le pointeur vers les chaînes de réseaux, et count capte la quantité de chaînes à l'aide de la fonction _countof . (Similaire à sizeof(arr) / sizeof(arr[0]) ).

et il ya Ansi supplémentaire pour conversion unicode en utilisant A2T macro, mais qui pourrait être facultatif pour votre cas.

0
répondu TarmoPikaro 2017-09-06 06:16:54

bonjour, vous pouvez essayer ce soufflet :

 char arr[nb_of_string][max_string_length]; 
 strcpy(arr[0], "word");

un bel exemple d'utilisation, tableau de chaînes en c si vous le voulez

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


int main(int argc, char *argv[]){

int i, j, k;

// to set you array
//const arr[nb_of_string][max_string_length]
char array[3][100];

char temp[100];
char word[100];

for (i = 0; i < 3; i++){
    printf("type word %d : ",i+1);
    scanf("%s", word);
    strcpy(array[i], word);
}

for (k=0; k<3-1; k++){
    for (i=0; i<3-1; i++)
    {
        for (j=0; j<strlen(array[i]); j++)
        {
            // if a letter ascii code is bigger we swap values
            if (array[i][j] > array[i+1][j])
            {
                strcpy(temp, array[i+1]);
                strcpy(array[i+1], array[i]);
                strcpy(array[i], temp);

                j = 999;
            }

            // if a letter ascii code is smaller we stop
            if (array[i][j] < array[i+1][j])
            {
                    j = 999;
            }

        }
    }
}

for (i=0; i<3; i++)
{
    printf("%s\n",array[i]);
}

return 0;
}
0
répondu Aominé 2018-05-20 07:23:39

une bonne façon est de définir une chaîne de caractères vous-même.

#include <stdio.h>
typedef char string[]
int main() {
    string test = "string";
    return 0;
}

c'est aussi simple que ça.

-6
répondu IceCodr 2014-05-25 14:33:07