J'essaye d'implémenter la fonction "int safecpy (char ** t, char * s)" et c'est pour copier un tableau dans un autre. J'ai en fait des problèmes avec l'utilisation des doubles pointeurs. La fonction renvoie 1 pour succès et 0 pour erreur. Je veux en fait imprimer le tableau copié mais je reste toujours bloqué ou le tableau n'est même pas affiché à la fin.
#include <stdio.h> #include <stdlib.h> #include <string.h> int safecpy(char **t, char *s); int main (void) { char *t, *v, i; char s[] = "abcd"; if (safecpy(&t, &s) == NULL) { printf("No memory."); return 1; } printf("The copied Array:"); for(i = 0; i < 4; i++) { printf("%i", t[i]); } free(t); return 0; } int safecpy(char **t, char *s) { int i; *t = malloc(strlen(s+1)*sizeof(char)); if (*t == NULL) { return NULL; } for(i = 0; i < (strlen(s)+1); i++) { *t[i] = s[i]; printf("i = %i\n", i); } return 1; }
J'ai essayé de remplacer * t [i] = s [i];
par t [i] = s [i]; code >. Ensuite, le for a parcouru tout le processus, mais je ne pouvais toujours pas imprimer
t
maintenant.
Quand je l'ai exécuté avec * t [i]
se bloque après i = i
et je ne comprends pas la raison. Ensuite, je ne suis pas sûr non plus en quoi l'ensemble de printf
et l'utilisation des doubles pointeurs sont corrects ici ou non.
3 Réponses :
Vous pouvez commencer par remplacer
printf("The copied Array:"); for(i = 0; i < strlen(s); i++) //don't use magic numbers { printf("%c", t[i]); // you want to see 'char' values, not `int` values }
par
printf("The copied Array:"); for(i = 0; i < 4; i++) { printf("%i", t[i]); }
par
sizeof (char)
est garanti à 1 en C. Aucun point ne l'utilisant comme multiplicateur. strlen (s + 1)
fait exactement le contraire de ce que vous pensez. Vous devez ajouter 1 à la longueur de la chaîne (la valeur renvoyée de strlen ()
), ne pas commencer à compter un après l'élément initial. Cela dit, conformément à la priorité des opérateurs , l'indice du tableau se lie avant l'opérateur de déréférencement du pointeur, vous devez donc appliquer la liaison expilitly en utilisant des parenthèses, car vous voulez que l'instruction soit analysée comme
*(t[i]) = s[i]; // default parsing without forced precedence.
pas comme p>
(*t)[i] = s[i]; // you want to index over the memory pointed to by (*t)
Quelques autres points:
if (safecpy (& t, & s) == NULL)
en if (safecpy (& t, s) == 0)
, car , le deuxième argument de safecpy ()
prend un char *
, et un nom de tableau, lorsqu'il est passé comme argument de fonction, se désintègre en pointeur vers le type emenelnt, dans ce cas , char *
. & array
serait de type char (*) [n]
, ce qui n'est pas la même chose que char *
. De plus, lorsque la fonction renvoie un int
, vous devez le comparer à une valeur int
. return NULL;
en return 0;
dans la fonction safecpy ()
, il renvoie un int
, pas un pointeur. main ()
, définir i
comme char
ne sert à rien, changez-le en int
. v
n'est pas utilisée, vous pouvez vous en débarrasser. Dans votre main ()
, l'extrait de code
*t = malloc(strlen(s) + 1);
doit être remplacé par
*t = malloc(strlen(s+1)*sizeof(char));
Tout d'abord, vouliez-vous dire
*t = malloc((strlen(s) + 1) * sizeof(char);
ou
*t = malloc(strlen(s+1) * sizeof(char));
?
Comme strlen (s + 1)
est égal à strlen (s) - 1
.
Concernant votre question, essayez (* t) [1] code>, donc vous déréférencer
char **
à char *
, puis déréférencer à char
à l'aide de l'opérateur d'accès aux membres [] .
return NULL
=》 return 0
Compilez les sources avec -Wall
et résolvez toujours les avertissements affichés, car le langage C vous permet de faire des opérations qui ont du sens pour le compilateur, mais qui ne sont pas correctes du point de vue de la programmation.
if (safecpy(&t, &s) == NULL)
Ah je vois ça a du sens! le compilateur a donné quelques avertissements avec -Wall -Wextra -ansi -pedantic mais le programme fonctionnait toujours
Il est recommandé d'utiliser l'option -Wall et de traiter chaque avertissement comme une erreur, car de nombreuses choses étranges peuvent se produire. Malheureusement, certains compilateurs ont certains avertissements désactivés, c'est pourquoi il est recommandé d'utiliser -Wall. Je me souviens d'un problème, quand il était possible d'appeler une fonction avec moins de paramètres que ce qui est défini, je suis resté coincé parce que je n'ai pas mis -Wall
malloc (strlen (s + 1) * sizeof (char))
doit êtremalloc (strlen (s) +1)
et* t [i] code> doit être
(* t) [i]
Votre compilateur devrait vous lancer des avertissements.
& s
n'est pas de typechar *
. Cependant,& s [0]
(qui est ce en quoi se désintègres
).ah sympa! :) Merci