web-dev-qa-db-fra.com

Faire un tableau pour tenir des tableaux de tableaux de caractères en C

Mon C est un peu plus que rouillé en ce moment, alors je ne parviens pas à créer quelque chose qui devrait être assez basique.

Permettez-moi de faire référence aux tableaux de caractères sous forme de chaînes pour cet article. Cela rendra les choses plus claires pour moi et pour vous.

Ce que j'ai est un tableau qui peut contenir une ou plusieurs chaînes. Par exemple {"ab", "cd", "ef"}. Je veux créer un autre tableau pour stocker plusieurs versions du tableau de chaînes. Donc quelque chose comme {{"ab", "cd", "ef"}, {"gh", "ij"}, {"kl"}}.

Ce que j'ai maintenant c'est:

char *arrayOfStrings[50]; // a single array to hold multiple strings
char **arrayOfArraysOfStrings[10]; // array to hold multiple snapshots of arrayOfStrings

Le tableau de chaînes change avec le temps et j'utilise le tableau de tableaux de chaînes pour stocker des instantanés historiques de arrayOfStrings. Mon problème survient lorsque je dois accéder au tableau d'instantanés pour les données. Voici le code que je dois mettre dans le tableau d'instantanés:

arrayOfArraysOfStrings[input_index] = arrayOfStrings; // you can assume input_index is updated correctly, I've already checked that.

Cela semble être incorrect, car lorsque j'essaie d'accéder au contenu du tableau d'instantanés et de l'imprimer, il imprime uniquement les informations du dernier tableau arrayOfStrings. L'idée que je voulais avec ceci était de stocker l'adresse de l'endroit où arrayOfChars pointe dans une entrée du tableau d'instantanés afin que je puisse y accéder plus tard.

À l'heure actuelle, l'accès à une entrée du tableau d'instantanés s'effectue de la manière suivante:

arrayOfArraysOfChars[historicalIndex][indexOfTargetChar]

Je cherche à répondre à plusieurs questions:

  1. La méthode que j'ai décrite convient-elle à ce que j'essaie de faire ou y a-t-il un défaut dans ma logique globale?
  2. Qu'est-ce que je fais de mal avec mon code actuel et comment puis-je le corriger?
  3. Existe-t-il un meilleur moyen de le faire et, dans l'affirmative, comment fonctionnent l'initialisation des tableaux, leur ajout et la lecture à partir des tableaux?

--edit 4/18 -- Une partie du problème vient du fait que je configure des pointeurs dans arrayOfArraysOfStrings afin qu'ils pointent vers la même chose que celle indiquée par arrayOfStrings. C'est mauvais puisque arrayOfStrings est édité. J'ai besoin d'un moyen de dupliquer un tableau 2D ... De préférence, en allouant simplement un nouveau bloc de mémoire pour que arrayOfStrings pointe vers.

15
Dae314

Vous avez un trop grand nombre d'indicateurs dans vos deux tableaux.

char arrayOfChars[50]; // a single array of characters
char *arrayOfArraysOfChars[10]; // array to hold multiple single arrays of characters

Puisque arrayOfChars est utilisé comme un tampon (les nouvelles données y vont toujours en premier), vous devez enregistrer une copie de la chaîne dans arrayOfArrays. La fonction POSIX strdup devrait aider ici.

Avis & et * sont des contraires, donc &* et *& ne font absolument rien.

Vous pouvez aussi faire littéralement cela avec arrayOfArrays.

char arrayOfChars[50]; // a single array of characters
char arrayOfArraysOfChars[10][50]; // array to hold multiple single arrays of characters

Avec cette configuration, vous devez utiliser strcpy pour copier les données dans arrayOfArrays.


Après avoir lu votre édition, je pense que vous devez commencer réel simple. Et FWIW, les noms de variables ne sont pas le bon Hongrois.

Pour ce que je pense que vous essayez de faire, je commencerais par un seul tableau de caractères. Ce sera le principal tampon, pour contenir les chaînes qui sont entrées et examinées.

enum { BUFSZ = 50 };
char buf[BUFSZ + 1];

Ensuite, vous pouvez l’utiliser avec fgets ou quoi que ce soit.

fgets(buf, BUFSZ, infile);

Pour les sauvegarder dans un tableau, j'utiliserais strdup pour son découpage automatique. Si les chaînes doivent comporter principalement 2 caractères, je ne souhaite pas que 48 octets supplémentaires soient utilisés pour chacun. Donc, un tableau de pointeurs de caractères (chaînes).

enum { STRVSZ = 40 };
char *strv[STRVSZ + 1];
int i;
i = 0;
strv[i] = strdup(buf);
strv[i+1] = NULL; // This makes it an "argv-style" NULL-terminated array of strings
++i; // i is now the index of the next element, and a count of elements already added

Chaque élément de strv est un pointeur de caractère. Mais pour préserver notre santé mentale, nous essayons de résumer certains détails distrayants pendant un moment, et de traiter chaînes comme un type de données distinct.

Maintenant, pour créer des listes de ceux-ci, nous faisons à nouveau la même chose. Mais il n’existe pas de fonction strdup- type permettant de dupliquer un tableau de pointeurs. Nous devons donc séparer l’attribution et la copie.

enum { STRVVSZ = 20 };
char **strvv[STRVVSZ + 1];
int j;
j = 0;
strvv[j] = calloc(i+1, sizeof *strvv[j]); // assuming i is the count of elements 
memcpy(strvv[j], strv, i * sizeof *strvv[j]);
++j; // j is now the index of the next string-pointer array in the array-of-same,
     // and a count of elements already added.

Maintenant, mes noms sont aussi bêtes que les vôtres, mais ils sont plus court!

16
luser droog

vous devriez apprendre ce que signifie un tableau . un tableau est fondamentalement un ensemble de entier ou caractère ou rien . lorsque vous stockez une valeur de caractère dans un tableau, le définir comme,

char array[] = {"somestringhere"};

maintenant vous voulez stocker de tels tableaux dans un autre tableau. C'est simple:

char* array1[];

le tableau 1 va stocker les valeurs, qui sont de type char*, c'est-à-dire l'adresse des tableaux de caractères . maintenant, vous voulez les stocker dans un autre tableau,

char** array2[];

c'est un tableau de [adresse des tableaux] maintenant, tout ce que vous avez à faire est;

array1[0] = array; //same as: array1[0] = *array[0];
array2[0] = *array1[0];

Maintenant, vous avez tout ce dont vous avez besoin… __. J'espère que vous êtes clair, au fond. :)

6
user2279942

Cet exemple a été réalisé avec turbo c ++ 1.01 dos et fonctionne également dans la version 3.0 dos.

char * text[] = {
  "message1",
  "message2",
  "message3"
};
3
steven tahner

Notez que vos exemples montrent des tableaux de pointeurs. Si vous souhaitez des tableaux de tableaux (tableaux multidimensionnels), spécifiez toutes les tailles dans la définition du tableau.

char sentences[500][42]; /* sentences is an array of 500 elements.
                         ** each element is itself an array
                         ** capable of holding strings up to length 41 */
2
pmg

si vous stockez du texte dans un fichier .c ou .h comportant plus d'une ligne de texte, cela équivaut à l'idée d'un tableau de tableaux de caractères. peut le faire:

char * text[] = {
  "message1",
  "message2",
  "message3"
};

peut aussi utiliser char * text [], char près de * text [], char far * text [], char énorme * text []. doit avoir un astérisque ou une étoile pour un pointeur.

une boucle for peut être utilisée pour afficher du texte:

char i; // int type can also be used
for (i = 0, i < 3; i++)
  printf("%s\n", text[i]);

autres boucles:

char i = 0;  // may not be zero when declared as "char i;" only
while (i < 3) {
  printf("%s\n", text[i]);
  i++;
 }

ou

char i = 0;  // may not be zero when declared as "char i;" only
do {
 printf("%s\n", text[i]);
 i++;
} while (i < 3);
1
steven tahner