Problema pasar matriz por referencia a una función en C

Iniciado por juligarc10, 25 Septiembre 2020, 13:49 PM

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

juligarc10

Hola amigos, estoy tratando de hacer una función que trocea una cadena, y la separa en los espacios, guardando cada palabra en una fila de la matriz. Para eso la paso por referencia (es decir, con un puntero) a la función trocear(), que ya he comprobado que funciona. Mi problema es que una vez que trocea, y en teoría se modifican los datos, no sé como acceder a los datos guardados. Paso código.

int trocear(char * cadena, char * trozos[])
{
        int i=1;
if ((trozos[0]=strtok(cadena," \n\t"))==NULL){
return 0;
//printf("%s\n", trozos[0]);
}
while ((trozos[i]=strtok(NULL," \n\t"))!=NULL){
//printf("%s\n", trozos[i]);
i++;
}
return i;
}

/*****************************************************************/

void procesarEntrada(char entrada[]){
char trozos[10][10];
//char *tr;
char *tr;
tr = trozos[0];
trocear(entrada, &tr);
}


Gracias de antemano. Un saludo.



MOD: Etiquetas de código GeSHi adaptadas a lenguaje C

K-YreX

Tienes varias opciones para hacer lo que quieres.

Si dejas la función trocear() tal y como la tienes, tienes que utilizar memoria dinámica:

#define SIZE 50
int main(){
    char *cadena = "Esta es una cadena de prueba";
    // Array bidimensional [SIZE][SIZE] con memoria dinamica:
    char **palabras = (char**)malloc(SIZE * sizeof(char*));
    for(size_t i = 0; i < SIZE; ++i){
        palabras[i] = (char*)malloc(SIZE * sizeof(char));
    }
    int numero_palabras = trocear(cadena, palabras);
    for(size_t i = 0; i < numero_palabras; ++i){
        printf("Palabra %i: %s\n", i+1, palabras[i]);
    }
    // Al terminar tienes que liberar la memoria reservada dinamicamente
    for(size_t i = 0; i < SIZE; ++i){
        free(palabras[i]);
    }
    free(palabras);
}


Si quieres usar un array de manera estática tienes que definir la función trocear() como:
int trocear(char *cadena, char palabras[][SIZE]);
(Es optativo especificar el tamaño de la primera dimensión de un array pero para el resto de dimensiones es obligatorio)
Código (cpp) [Seleccionar]

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

juligarc10

Cita de: K-YreX en 25 Septiembre 2020, 17:17 PM
Tienes varias opciones para hacer lo que quieres.

Si dejas la función trocear() tal y como la tienes, tienes que utilizar memoria dinámica:

#define SIZE 50
int main(){
    char *cadena = "Esta es una cadena de prueba";
    // Array bidimensional [SIZE][SIZE] con memoria dinamica:
    char **palabras = (char**)malloc(SIZE * sizeof(char*));
    for(size_t i = 0; i < SIZE; ++i){
        palabras[i] = (char*)malloc(SIZE * sizeof(char));
    }
    int numero_palabras = trocear(cadena, palabras);
    for(size_t i = 0; i < numero_palabras; ++i){
        printf("Palabra %i: %s\n", i+1, palabras[i]);
    }
    // Al terminar tienes que liberar la memoria reservada dinamicamente
    for(size_t i = 0; i < SIZE; ++i){
        free(palabras[i]);
    }
    free(palabras);
}


Si quieres usar un array de manera estática tienes que definir la función trocear() como:
int trocear(char *cadena, char palabras[][SIZE]);
(Es optativo especificar el tamaño de la primera dimensión de un array pero para el resto de dimensiones es obligatorio)

Muchas gracias por tu respuesta, ha sido de gran ayuda. De todas formas me gustaría preguntarte como implementaría la segunda opción. Le pasaría a la función un char palabras[][SIZE], pero despues como operaría con el dentro de la función? Me refiero sobre todo a los strtok y eso...

Gracias.

K-YreX

En el caso de utilizar la función:
int trocear(char cadena[], char trozos[][SIZE]);
tendrías que crear un puntero a char para usarlo en la función strtok y después copiar su contenido mediante strncpy().
Además lo suyo sería pasar como tercer parámetro el número de filas de <trozos> para evitar problemas de acceso en la función.

int trocear(char cadena[], char trozos[][SIZE], int filas){
  int num_trozos = 0;
  char *p = strtok(cadena, " \n\t");
  while(p && num_trozos < filas){
    strncpy(p, trozos[num_trozos], SIZE);
    trozos[num_trozos++][SIZE-1] = '\0'; // para asegurar que cada trozo acaba con \0
    p = strtok(NULL, " \n\t");
  }
  return num_trozos;
}
Código (cpp) [Seleccionar]

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