1
votes

Comment travailler avec des pointeurs doubles et printf dans int safecpy (char ** t, char * s)?

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 commentaires

malloc (strlen (s + 1) * sizeof (char)) doit être malloc (strlen (s) +1) et * t [i] doit être (* t) [i]


Votre compilateur devrait vous lancer des avertissements. & s n'est pas de type char * . Cependant, & s [0] (qui est ce en quoi se désintègre s ).


ah sympa! :) Merci


3 Réponses :


1
votes

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:

  • Vous devez changer l'appel 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 .
  • Modifiez return NULL; en return 0; dans la fonction safecpy () , il renvoie un int , pas un pointeur.
  • Dans main () , définir i comme char ne sert à rien, changez-le en int .
  • La variable 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));
    


0 commentaires

0
votes

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 [] .


2 commentaires

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.



0
votes
if (safecpy(&t, &s) == NULL)

2 commentaires

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