¿Por qué la salida es la última cadena del usuario?

#include #include int main() { int in,i,j; char *arr[100],str[14]; scanf("%d",&in); i=0; while(i<in) { scanf("%s",str); arr[i]=str; // printf("%s\n",arr[i]); i++; } i=0; while(i<in) { printf("%s\n",arr[i++]); } return 0; } 

/ * en este código tomé las cadenas de entrada del usuario y quiero imprimirlas de nuevo, pero está imprimiendo la última entrada de la cadena por parte del usuario. ¿POR QUÉ? * /

Está almacenando cada cadena en el mismo lugar, sobrescribiendo la cadena anterior cada vez. No hagas eso str es un búfer, y todos los punteros de la matriz arr lo apuntan.

Tu problema es arr[i]=str; statement.

str es una matriz asignada estáticamente, y todos los arr[i] almacenan la dirección base de la misma.

Como el valor de str se sobrescribe en cada llamada a scanf() , en su caso, solo se imprimirá el último valor almacenado en str accediendo a arr[i] .

Qué necesitas hacer

  1. Asignar memoria dinámicamente a arr[100] .
  2. use strcpy() para copiar la entrada del usuario de str a arr[i]

Nota: No olvides free() la memoria asignada.

Debido a que está asignando la dirección de memoria a la matriz de puntero. Así que la dirección de la matriz no se cambiará. Cada matriz de puntero está apuntando a la misma dirección.

Cuando se obtiene el nuevo valor, se colocará ese valor en la matriz en la misma posición de dirección.

Así que todos los valores siguen siendo los mismos. Así que evita esto, puedes hacer la cadena para apuntar. Y asigna la memoria a ese puntero dinámicamente.

char *str; Haz la asignación en while loop str=malloc(MAX);

 while(i 

100 es un ejemplo. Puedes usar tu valor necesario.

Intenta algo como esto en tu bucle.

 while(i 

Porque sigues usando el mismo char[] str para todas las cadenas.

En su lugar, es probable que desee asignar un nuevo bloque de memoria para cada cadena. No te olvides de liberarlos de nuevo después de usarlos.

Puedes comprobarlo en el bucle.

 while(i 

y verá que no solo la cadena es la misma, sino también su dirección.

Debe asignar memoria para cada cadena arr[i] y luego usar strcpy para copiar la cadena.

Agrega algún código como abajo en tu bucle.

 arr[i]=malloc(strlen(str)+1); strcpy(arr[i],str); 

Además, nunca se olvidó de liberar memoria para la asignación anterior al final del progtwig.

Además de las otras respuestas, hay algunas formas alternativas de acercarse a la lectura de entrada de cadena que puede usar para simplificar lo que necesita hacer un seguimiento del progtwig. Como otros sugirieron, en lugar de declarar arr como char *arr[100] , siga adelante y declare que es un pointer-to-pointer-to-char .

 char **arr = NULL; 

Esto le permite asignar una matriz de punteros de caracteres. Puede elegir asignar con malloc o puede asignar e inicializar todos los punteros a zero/NULL simplemente usando calloc lugar.

 arr = calloc (100, sizeof *arr); 

Al usar calloc , esto permite una iteración posterior sobre solo aquellos punteros que contienen cadenas. Esto elimina aún más la necesidad de solicitar el número de cadenas para ingresar (o hacer un seguimiento de cuántas se ingresaron).

Después de que haya asignado sus punteros, debe asignar espacio para mantener cada cadena. Si bien no hay nada malo con otra llamada a malloc (o calloc ) y luego una llamada a strcpy (o strncpy ), puede hacer ambas cosas a la vez con la función strdup proporcionada en string.h . Lo único que strdup tener en cuenta con strdup es que te está asignando memoria. Por lo tanto, usted es responsable de liberar esa memoria cuando ya no la necesite.

Al juntar las piezas, así como la información del comentario con respecto a su cadena scanf , puede implementar su colección de cadenas de la siguiente manera. Nota Simplemente ingrese tantas cadenas como desee (hasta los 100 punteros asignados inicialmente), luego presione [enter] en una línea en blanco cuando haya terminado:

 #include  #include  #include  int main () { int i = 0; /* always initialize your variables */ char **arr = NULL; char str[14] = { 0 }; arr = calloc (100, sizeof *arr); /* create 100 pointers to char* */ printf ("\nEnter strings ( [enter] alone when done )\n\n"); while (printf (" input: ") && scanf ("%[^\n]%*c", str) >= 1) arr[i++] = strdup (str); /* strdup allocates and copies */ printf ("\nThe strings entered were:\n\n"); i = 0; /* print the array */ while (arr[i]) { printf (" arr[%2d]: %s\n", i, arr[i]); i++; } i = 0; /* free memory allocated */ while (arr[i]) free (arr[i++]); if (arr) free (arr); return 0; } 

salida:

 $ ./bin/str_array Enter strings ( [enter] alone when done ) input: string 1 input: string 2 input: string 3 input: The strings entered were: arr[ 0]: string 1 arr[ 1]: string 2 arr[ 2]: string 3 

Hay muchas, muchas maneras de abordar este problema. Compara todas las respuestas y agrega los diferentes enfoques a tu colección. Siempre hay lugares donde uno tendrá beneficios sobre el otro, y viceversa. Tenga en cuenta que, en el código anterior, debe verificar si alguna asignación con calloc , malloc o strdup exitosa y manejar el error si falla. También debe verificar cuando llegue a la puntada 99 ingresada y reasignar el número de punteros según sea necesario. Esos controles se omiten para mayor claridad.

Resumen de uso de memoria valgrind

Adquiera el hábito de verificar siempre el uso de su memoria con valgrind . Señalará cualquier lugar donde haya asignado memoria que no haya podido liberar. Si bien la memoria en un pequeño fragmento de código como este se liberará al exit , en un código más largo, si no se mantiene un registro de la memoria que asigna, el progtwig podrá utilizar una cantidad significativa de memoria después de que ya no sea necesaria (memoria fugas). Una comprobación rápida con valgrind revelará cualquier problema o confirmará que todo está bien:

 ==28677== HEAP SUMMARY: ==28677== in use at exit: 0 bytes in 0 blocks ==28677== total heap usage: 4 allocs, 4 frees, 827 bytes allocated ==28677== ==28677== All heap blocks were freed -- no leaks are possible ==28677== ==28677== For counts of detected and suppressed errors, rerun with: -v ==28677== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 

Hazme saber si tienes alguna pregunta.