Comment capturer une chaîne d’une fonction en C qui renvoie une chaîne?

Je suis nouveau sur C et j’ai créé le code suivant, mais lorsqu’il est exécuté, le programme se bloque. Pourquoi? Comment puis-je l’empêcher de s’écraser?

char *get() { char *n; printf("\n user name : "); scanf("%s", &n); return n; } int main() { char *c = get(); printf("%s", c); return 0; } 

En C, il est typique que le parent gère l’allocation de mémoire puisqu’il n’y a pas de récupérateur de mémoire à nettoyer après vous-même, il doit donc le faire de toute façon:

 void get(char *n) { printf("\n user name : "); scanf("%s", n); } int main() { char c[200]; get(c); printf("%s", c); return 0; } 

http://ideone.com/Tw347

scanf lit les caractères de stdin et les stocke dans la mémoire sur laquelle pointe n . Vous n’avez pas initialisé n pour indiquer quoi que ce soit, donc scanf tente probablement de stocker votre entrée dans un emplacement quelconque de la mémoire. Vous avez de la chance qu’il se soit écrasé plutôt que d’agir calmement comme s’il fonctionnait correctement.

Renvoyer une chaîne depuis une fonction C est plus complexe que prévu.

Il y a (au moins) trois approches générales:

  1. Demander à l’appelant de passer un pointeur sur (le premier élément de) un tableau dans lequel la chaîne doit être stockée, ainsi qu’un autre argument indiquant à la fonction la taille du tableau. Cela peut nécessiter un traitement d’erreur si le tableau n’est pas assez grand pour contenir le résultat.

  2. Déclarez un tableau static à l’intérieur de la fonction et renvoyez-lui un pointeur. (Vous ne pouvez pas renvoyer un pointeur sur un tableau local non statique, car ce tableau cesse d’exister lorsque la fonction est renvoyée.) Problèmes: plusieurs appels utilisent le même espace de stockage (particulièrement problématique en présence de threads), et la taille est fixée.

  3. Atsortingbuez le résultat dans la fonction à l’aide de malloc() . Cela nécessite que l’appelant free() le résultat.

Lecture recommandée: la FAQ comp.lang.c. En particulier, la question 7.5b est presque une réponse directe à votre question (et m’aurait épargné un peu de frappe si je l’avais déjà réalisé plus tôt). (Je ne fais généralement pas de lien vers des questions individuelles parce que j’aime encourager les gens à naviguer.)

EDIT: De plus, scanf avec un format "%s" non qualifié est insortingnsèquement dangereux. Il essaiera de stocker quel que soit le nombre de caractères entrés dans le tableau. il n’y a aucun moyen d’éviter les dépassements de tampon (par exemple, si votre chat est assis sur le clavier) @Artefacto a fait référence à ce problème dans le lien dans le commentaire.

Tout d’abord, vous devez allouer de la mémoire pour votre chaîne

vous pouvez le faire dynamicment en utilisant malloc;

par exemple avec une taille de 200 :

 #include  char (*n)[200] = malloc(sizeof *n); 

n’oubliez pas de libérer le pointeur avec

 free(n);