Arreglos de cadenas en C

Iniciado por 024mc, 2 Junio 2020, 00:02 AM

0 Miembros y 1 Visitante están viendo este tema.

024mc

Hola
Cómo puedo crear un arreglo para guardar nombres de personas con espacios, dados por teclado?


K-YreX

Una cadena con espacios tiene la misma representación que una sin espacios ya que un espacio también es un char.
La cadena la puedes reservar de forma estática:

#define SIZE 50
char cadena[50];

O de forma dinámica:

#define SIZE 50
char *cadena = (char*)malloc(SIZE * sizeof(char));

Recuerda que si lo haces de forma dinámica, luego tienes que liberar la memoria reservada:
free(cadena);

Para poder guardar espacios lo importante es usar la función fgets() en vez de scanf().

fgets(cadena, SIZE, stdin);

Esto guardará el ENTER que pulses al final como parte de la cadena (siempre que no hayas llegado a los SIZE-1 caracteres, ya que el último se reserva para el carácter de fin de cadena '\0'). Para eliminar el salto de línea producido por el ENTER:

if(cadena[strlen(cadena)-1] == '\n')
  cadena[strlen(cadena)-1] = '\0';
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

michellcrh

#2
Y si quiero meter varias cadenas a un mismo arreglo?
Lo que sucede es que estoy intentando llenar un arreglo con datos que ya tengo en una estructura y en este caso solo necesito llenarlo con los nombres.
Mas o menos tendría un opción en donde se pediría que nombres quiero meter al arreglo y conforme me los vaya ingresando la persona, se iría llenando el array.

K-YreX

Ah vale, creo que te había entendido mal.

Si lo que quieres es un arreglo de cadenas y una cadena es un arreglo, lo que tienes al final es un arreglo de arreglos, es decir, un arreglo bidimensional o matriz.
Si lo que intentas es meter diferentes nombres en la misma cadena y separarlos solo por un espacio, si los nombres son independientes, creo que sería mejor opción una matriz en la que cada fila es un nombre.

Si por lo que sea quieres juntar todos los nombres en la misma cadena tendrías que copiar un nombre en la cadena final, insertar un espacio, copiar otro nombre,...

No sé si es eso a lo que te refieres ni dónde tienes exactamente el problema. Si para crear la cadena, para introducir las otras cadenas, para introducir los espacios... :huh: :huh:
Si no es eso, seguramente sea más sencillo si pones un ejemplo concreto de código.
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

michellcrh

Te lo agradezco mucho, mas o menos esta es la funcion que quería hacer pero no logro que conforme me vaya digitando el numero del nombre que desea meter al arreglo, este se vaya llenando.

void mostrarNombres(Persona *personas, int numeroPersonas){
    int opcion,opc;
    char arregloPersonas[50][LIMITE]; // limite = 100
    do{
        for(int i = 0; i < numeroPersonas; i++){
    printf("%d Nombre: %s\n", i+1,personas[i].nombre);
    printf("\n\n");
   }

   printf(" Ingrese el numero correspondiente al nombre que desea: ");
       scanf("%d",&opcion);

       for(int j=0; j<numeroLibros; j++){
           if(opcion == j+1){
               //En este caso la persona con el numero que ingrese deberia guardarse en el arreglo, y es lo que no funciona
               //personas[j].nombre

           }
       }

       printf(" Desea agregar otro nombre?, 1 = SI , 2 = NO: ");
       scanf("%d",&opc);
       system("cls");
    }while(opc == 1);
    if(opc == 2){
        printf("\nNOMBRES AGREGADOS:\n");
        for(int i=0; i<numeroPersonas;i++){
             printf("%s\n",arregloPersonas[i]);
        }

    }
    else{
        printf("ERROR, OPCION NO VALIDA");
    }



}


ErahUnderground

¿Puede ser que no tengas declarada la variable 'numeroLibros'?

No sé si entiendo bien el ejercicio, pero si por ejemplo el número de libros de una persona está dentro de tu array de estructuras personas tendrías que hacer el for de la j así:


for(int j=0; j<personas[opcion].numeroLibros; j++)


A parte de eso, date cuenta que estás seleccionando a una persona y después estás buscando una opción (que es la persona) e intentandola comparar con el número del libro.

K-YreX

Cita de: michellcrh en  2 Junio 2020, 03:44 AM
Te lo agradezco mucho, mas o menos esta es la funcion que quería hacer pero no logro que conforme me vaya digitando el numero del nombre que desea meter al arreglo, este se vaya llenando.

void mostrarNombres(Persona *personas, int numeroPersonas){
    int opcion,opc;
    char arregloPersonas[50][LIMITE]; // limite = 100
    do{
        for(int i = 0; i < numeroPersonas; i++){
    printf("%d Nombre: %s\n", i+1,personas[i].nombre);
    printf("\n\n");
   }

   printf(" Ingrese el numero correspondiente al nombre que desea: ");
       scanf("%d",&opcion);

       for(int j=0; j<numeroLibros; j++){
           if(opcion == j+1){
               //En este caso la persona con el numero que ingrese deberia guardarse en el arreglo, y es lo que no funciona
               //personas[j].nombre

           }
       }

       printf(" Desea agregar otro nombre?, 1 = SI , 2 = NO: ");
       scanf("%d",&opc);
       system("cls");
    }while(opc == 1);
    if(opc == 2){
        printf("\nNOMBRES AGREGADOS:\n");
        for(int i=0; i<numeroPersonas;i++){
             printf("%s\n",arregloPersonas[i]);
        }

    }
    else{
        printf("ERROR, OPCION NO VALIDA");
    }
}

Como te ha dicho @ErahUnderground, la variable numeroLibros que utilizas no aparece definida en ningún sitio.
Me da la sensación de que querías usar numeroPersonas ya que tiene más sentido así que mi respuesta irá por esa línea.

Daré por hecho que numeroPersonas contiene la cantidad de personas almacenadas en el array personas. Entonces te falta otro índice para ir guardando en arregloPersonas ya que si no usas otro índice guardarás a la persona 40 en la fila 40 y habrás desperdiciado las anteriores filas de arregloPersonas.
El resultado sería:

void mostrarNombres(Persona *personas, int numeroPersonas){
    int opcion;
    int indicePersona; // indice de la persona a guardar
    char arregloPersonas[50][LIMITE]; // limite = 100
    int personasGuardadas = 0; // personas guardadas en arregloPersonas

    do {
        // Otro bucle para evitar que se introduzca un indice fuera de los limites permitidos
        do {
            printf("Numero de la persona a almacenar [%d - %d]: ", 1, numeroPersonas);
            scanf("%d", &indicePersona);
        } while(indicePersona < 1 || indicePersona > numeroPersonas);

        // Ahora no tenemos que recorrer el bucle, accedemos directamente al indice:
        // Para copiar cadenas, usa strncpy:
        strncpy(arregloPersonas[personasGuardadas], personas[indicePersona-1], LIMITE); // Al segundo le restamos 1 porque pedimos un indice empezado en 1 pero los arrays en C empiezan en 0.
        arregloPersonas[personasGuardadas][LIMITE-1] = '\0'; // Para curarme en salud y asegurarme que la cadena tiene un caracter de fin de cadena
        ++personasGuardadas;

        // Si no hemos llegado al limite, le dejamos al usuario elegir:
        if(personasGuardadas < 50){
            // Otro bucle para que la opcion sea 1 o 2:
            do {
                printf("Guardar otro nombre (1 = Si / 2 = No): ");
                scanf("%d", &opcion);
            } while(opcion != 1 && opcion != 2);
        }
    } while(personasGuardadas < 50 && opcion == 1);

    // Aqui ya puedes mostrar los nombres guardados usando como limite <personasGuardadas>:
    printf("Los nombres guardados son:\n");
    for(int i = 0; i < personasGuardadas; ++i){
        printf("%s\n", arregloPersonas[i]);
    }
}
Código (cpp) [Seleccionar]

cout << "Todos tenemos un defecto, un error en nuestro código" << endl;

michellcrh

Te lo agradezco mucho, me ayudó bastante.