¿Cómo puedo capturar una cadena desde una función en C que devuelve una cadena?

Soy nuevo en C y he creado el siguiente código, pero cuando se ejecuta el progtwig se bloquea. ¿Por qué? ¿Cómo lo detengo?

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, es típico que el padre maneje la asignación de memoria, ya que no hay ningún recolector de basura para limpiar después de ti, así que tiene que hacerlo de todos modos:

 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 está leyendo caracteres de la stdin y almacenándolos en la memoria que apunta a. No ha inicializado n para señalar nada, por lo que scanf probablemente está tratando de almacenar su entrada en una ubicación arbitraria en la memoria. Tienes suerte de que se haya estrellado en lugar de actuar silenciosamente como si estuviera funcionando correctamente.

Devolver una cadena desde una función C es más complejo de lo que cabría esperar.

Hay (al menos) tres enfoques generales:

  1. Requerir que la persona que llama pase un puntero a (el primer elemento de) una matriz en la que se almacenará la cadena, junto con otro argumento que indica a la función qué tan grande es la matriz. Esto puede requerir manejo de errores si la matriz no es lo suficientemente grande como para contener el resultado.

  2. Declare una matriz static dentro de la función y devuelva un puntero a ella. (No puede devolver un puntero a una matriz local no estática, ya que la matriz deja de existir cuando se devuelve la función). Problemas: varias llamadas utilizan el mismo espacio de almacenamiento (especialmente problemático en presencia de hilos), y el el tamaño es fijo

  3. Asigne el resultado dentro de la función usando malloc() . Esto requiere que la persona que llama free() el resultado.

Lectura recomendada: la comp.lang.c FAQ . En particular, la pregunta 7.5b es casi una respuesta directa a tu pregunta (y me hubiera ahorrado escribir algo si me hubiera dado cuenta antes). (No suelo vincular a preguntas individuales porque me gusta animar a las personas a navegar).

EDITAR: Además, scanf con un formato "%s" no calificado es inherentemente inseguro. Intentará almacenar, sin embargo, se ingresan muchos caracteres en la matriz; no hay forma de evitar el exceso de búfer (por ejemplo, si su gato se sienta en el teclado). @Artefacto hizo referencia a este problema en el enlace del comentario.

En primer lugar debes asignar memoria para tu cadena

Puedes hacerlo dinámicamente usando malloc;

por ejemplo con un tamaño de 200 :

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

no te olvides de liberar el puntero con

 free(n);