C: Problema trabajando con matrices

Buenas, estoy realizando hace tiempo un programa en C, y me he topado con un gran problema a la hora de pasar matrices entre funciones:

Tengo una funcion TrataParametros(int fargc, char **fargv), que lo que hace es tratar los parámetros que me entran por comandos, mediante getopts() (MIL gracias por recomendarmelo ferdy).

Pueden entrarme los parametros mediante dos formas:

1. Por linea de comandos
2. Mediante un fichero con líneas del mismo estilo que si de parámetros se tratase.

Si me lo entran por línea de comandos no hay problema, le paso argc y argv a la funcion TrataParametros, y solucionado. TrataParametros(argc,argv).

***Nota aclaratoria antes de seguir, a partir de ahora, el trabajo lo realizo dentro de la función TrataFichero(char *fichero);

Pero el problema está en que si leo una línea del fichero, y la "desguazo" y almaceno los parametros en un array definido de la siguiente forma: char fargvv[30][20]; (como he dicho antes dentro de TrataFichero()).

Luego al pasarlo a TrataParametros(fargcc,fargvv); el compilador me da el warning:

parametres.c: In function 'TrataFichero':
parametres.c:347: warning: passing argument 2 of 'TrataParametros' from incompatible pointer type

***Fin aclaración

y si ejecuto la aplicación peta (segmentation fault) cuando intento tratar fargv dentro de la funcion TrataParametros();

He pensado en añadir un parámetro en la funcion TrataParametros, de forma que reciba (int, char **, char [30][20]) y marcar como NULL el segundo o el tercero según de donde vengan los parametros, pero tengo el mismo problema, porque getopts() solo acepta char **, y si le entro char [30][20] da segmentation fault.

Haber si alguien me puede echar una mano, porque estoy trabado en esta parte de mala manera...

Saludos y mil gracias por adelantado!!!
Hombre, yo creo que si postearas un poco del código sería más fácil, así sólo con la explicación no se me ocurre nada.

salu2!
Buenas, bueno, no he posteado codigo porque no lo he creído oportuno, aparte que son 1500 líneas de codigo... Creo que mi problema se entiende en el primer post, pero básicamente és, que en una función tengo una matriz declarada como char matriz[30][20], i tengo que recojerla en otra que está declarada char **matriz. Y como son distintos tipos de datos pues da el error.

De todas formas los trozos de codigo que creo son mas importantes son los siguientes:

MAIN:

int main(int argc,char **argv)
{
 
   if (strcmp(argv[1],"--file")==0 || strcmp(argv[1],"-f")==0 && argc==3)
      TrataFichero(argv[2]);
   else
      TrataParametros(argc,argv);
      
   exit (EXIT_SUCCESS);
}//main


Función TrataParametros:

void TrataParametros(int fargc, char **fargv)//AQUI RECIBE LA DIRECCION DE LA MATRIZ, Y NO APUNTA A LA MATRIZ
{
        .................................................................................//aqui habría mas codigo
   while(1) //en el while trato los parametros con getopt_long()
   {
         opcio=getopt_long (fargc, fargv, opCurtes, opLlargues, NULL);
//llamada a getopt_long()AQUI ES DONDE DA LA VIOLACIÓN DE SEGMENTO .........................................//seguiría la función


Funcion TrataFichero:
void TrataFichero(char *fitxer)
{
   unsigned int fargc,entra,i;
   char s1[100];
   char s2[4]=" \n\t";
   char *ptr;
   char fargv[30][20]; //DECLARACIÓN DE LA MATRIZ
   
   if ((arxiu=fopen(fitxer,"r")) == NULL)
   {
      ErrorP('7',fitxer);
      exit(EXIT_FAILURE);
   }
   else
   {
      strcpy(fargv[0],NOM);
      mode=1;
      
      while (!feof(arxiu))
      {
         fargc=1;
         entra=0;
         fgets(s1,100,arxiu);
         ptr = strtok( s1, s2 );
         
         if (ptr!=NULL)
         {
            strcpy(fargv[fargc],ptr);
            
            while( (ptr = strtok( NULL, s2 )) != NULL )
            {
               entra=1;
               fargc++;
               strcpy(fargv[fargc],ptr);
            }
            fargc++;
            if (entra==1)
               TrataParametros(fargc,fargv); //AQUI ES DONDE PASO EL ARGUMENTO Y NO LO PUEDE LEER PORQUE LOS CONSIDERA DIFERENTES TIPOS DE DATOS
               }
         
         mode++;
      }
      
      fclose(arxiu);
   }
}


Gracias y saludos!!
En primer lugar cometes un error : le has dado un tamaño a tu matriz de 30 y luego la recorres con un while (!feof), lo que haría que pueda entrar en matriz[40] si hubiera 40 líneas. Si solventas esto con una reserva dinámica de memoria (haciendo reallocs a cada parámetro nuevo que encuentra) solventarías también tu problema a la hora de pasar como argumento a la función.

Un saludo, corregidme si he dicho algo que no sea cierto ;).

P.D. Es mucho mejor que en el tratamiento de cadenas de caracteres trabajes con variables dinámicas, ya que el tamaño de las cadenas en un fichero puede ser variable y por lo tanto usas exactamente la memoria necesaria, a parte que puede haber en el fichero cadenas de más de 100 caracteres que no serían leídas.
Hola Jaime, el 30 no marcaba las líneas del archivo, sino el número de argumentos por línea.

Te he hecho caso a la hora de hacerlo de forma dinámica, y ahora el programa va de fábula...... Para la primera línea... Porque ahora asigno la memoria y la libero despues de tratar cada línea del fichero, pero cuando vuelvo a crear la memoria para la segunda línea del fichero, le asigno los argumentos y lo paso a TrataParametros(), getopt() devuelve -1, como si ya no hubieran más parámetros a tratar... Y entonces pues, pasa de la segunda y posteriores líneas. Veis algo mal en la función? De todas formas, he sacado por pantalla en la función TrataParametros() el contenido de la matriz y me la ha sacado sin mayores problemas...

void TrataFichero(char *fitxer)
{
   unsigned int fargc,entra,i;
   char s1[100];
   char s2[4]=" \n\t";
   char *ptr;
   char **fargv;
   
   if ((arxiu=fopen(fitxer,"r")) == NULL)
   {
      ErrorP('7',fitxer);
      exit(EXIT_FAILURE);
   }
   else
   {
      mode=1;
      while (!feof(arxiu))
      {
         fargv=(char **)malloc(sizeof(char *)*30);
         fargv[0]=(char *)malloc(sizeof(NOM));
         strcpy(fargv[0],NOM);
         
         fargc=1;
         entra=0;
         fgets(s1,100,arxiu);
         ptr = strtok( s1, s2 );
         
         if (ptr!=NULL)
         {
            fargv[fargc]=(char *)malloc(sizeof(ptr));
            strcpy(fargv[fargc],ptr);
            
            while( (ptr = strtok( NULL, s2 )) != NULL )
            {
               entra=1;
               fargc++;
               fargv[fargc]=(char *)malloc(sizeof(ptr));
               strcpy(fargv[fargc],ptr);
            }
            fargc++;
            printf("%d",fargc);
            if (entra==1)
               TrataParametros(fargc,fargv);
            for (i=(fargc-1);i>0;i--)
               free(fargv[i]);
            free(fargv);
         }
         
         mode++;//marcará la línea que s'està tractant als paràmetres a l'hora de donar error.
      }
      
      fclose(arxiu);
   }
}


Saludos y gracias!!
4 respuestas