[ Foro de C ]

Crear una lista de strings en C

08-Apr-2018 16:10
Invitado (JoseVald)
2 Respuestas

Hola SúperNacho! Soy Jose Valdés, te acuerdas de mí?? Vuelvo a darte por saco después de estos años porque estoy viéndome las caras con C y nos llevamos regular por ahora.

Verás, estoy intentando hacer una función que reciba un string y me devuelva una lista de strings con cada una de las lineas. Eso, en cualquier otro lenguaje sería poco más que un simple split separando por \n, pero en C la cosa se complica.

He leído tu manual de C de nachocabanes.com y en el apartado 9.7 tengo "la respuesta". Me encuentro con que para hacer un array de strings se hace así [copio literalmente de tu web]:

   char *mensajesError[3]={"Fichero no encontrado",
     "No se puede escribir",
     "Fichero sin datos"};

   printf("El primer mensaje de error es: %s\n",
     mensajesError[0]);
   printf("El segundo mensaje de error es: %s\n",
     mensajesError[1]);
   printf("El tercer mensaje de error es: %s\n",
     mensajesError[2]);    


El caso es que si en vez de hacer eso, lo que hago es (pseudocódigo):

   int numLineas = obtenerNumLineas();
   char *miLista[numLineas];
   int i = 0;
   while(i < numLineas) {
       miLista[i] = getLineaActual();
       i++;
   }


Esto no funciona. En resumen, si hago


   char *miLista[numLineas]; -> no funciona

si hago


   char *miLista[12]; -> sí funciona

Es decir, si en vez de poner una variable entre los corchetes, meto un int a mano, sí funciona. Me estoy volviendo loco, la verdad.. algún consejo? Alguna otra forma de hacer esa lista de manera dinámica?


09-Apr-2018 12:55
Nacho Cabanes (+83)

Claro que te recuerdo, Jose.  :-)

Por una parte, para saber la cantidad de datos tendrás que contar espacios, y puedes usar directamente la notación "char **" para representar un "array de arrays de caracteres" cuyo tamaño no sabes inicialmente.

Por otra parte, para este tipo de operaciones, ¿has mirado la función "strtok"? Es la forma "oficial" de partir una frase en "tokens" con C.

Y finalmente... ¿de verdad necesitas hacer esas cosas con C puro y duro como en los años 70?  ¿No puedes usar al menos C++?
 


10-Apr-2018 20:00
Invitado (JoseValdes)

Hola Nacho!

Ya lo solucioné!

Me explico. Es una forma muy correcta la que expones en tu manual:

char *lista[12]. De hecho, en linux me funciona, pero en mac no, por lo visto esa forma solamente es compatible desde C99 en adelante..

Entonces, como bien has dicho, he usado otra forma.

char **lista = (char **)malloc(numLineas * sizeof(char *));

y luego la relleno con un for y en cada linea hago

lista[i] = (char *) malloc (strlen(cadena) * sizeof(char));
lista[i] = cadena;

Si no hago los malloc me encuentro con un bonito Fragmentation Error.

Ahora tengo otra duda.. cuándo tengo que hacer free? Es decir, si llamo a un método que devuelve una lista inicializada con malloc, y esa lista la uso en otros métodos.. cuándo es el momento adecuado para hacer free?

Y por cierto, no puedo hacerlo con C++, tiene que ser obligatoriamente con C xDDD
Es una práctica de la universidad, tengo que hacer un servidor web hecho enteramente con C. La verdad es que es una práctica muy chula con la que estoy aprendiendo mucho. Es la primera vez que me veo las caras con C y bueno.. parece que ya nos estamos empezando a llevar bien xDD

En fin, como siempre.. muchísisisisimas gracias!!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)