Discussion:
Tratar Directorios en C
(demasiado antiguo para responder)
aioritos
2005-07-21 11:50:35 UTC
Permalink
Hola, tengo un problemilla con el siguiente codigo:


int download_file(int control_id)
{
int data_id,errorlevel;
char listing[BUFFER];
char dirname[255];
FILE *local_file;

struct dirent *dentry;

if(getcwd(dirname, 255)==0)
return FALSE;

/*Tengo que quitar Cliente*/
errorlevel=strlen(dirname);
errorlevel=errorlevel-7;/*strlen("Cliente");*/
dirname[errorlevel]='\0';

strcat(dirname,"Servidor/");
strcat(dirname,Num_Empresa);/*Variable global tipo char* */

/*loerrorlevel=strlen(dirname);
dirname[errorlevel]='\0';*/
/*ya tengo direccion para pedir archivos*/
DIR *d=opendir(dirname); /* NULL en caso de error */
if(d==0)
perror("fa");

puts("fin3");
dentry=readdir(d);
puts("fin4");
while(dentry!=0){
if(strcmp(dentry->d_name, ".")==0 || strcmp(dentry->d_name,
"..")==0){
dentry=readdir(d);/*Si es . ó .., lee el siguiente anda*/
}


A simple vista no parece que este mal; de hecho puesto en un nuevo
fichero fuente funciona!!!

Pero dentro de este codigo no. Alguien tiene mas vista que yo?? Bueno
decir que al bucle while no llega, ni tampoco a imprimir fin4, con lo
que deduzco que el "Sementation fault" se origina en el readdir

Gracias.
Oscar Garcia
2005-07-21 19:42:51 UTC
Permalink
Post by aioritos
/*Tengo que quitar Cliente*/
errorlevel=strlen(dirname);
errorlevel=errorlevel-7;/*strlen("Cliente");*/
dirname[errorlevel]='\0';
Procura no hacer eso NUNCA si no compruebas antes que errorlevel sea
mayor o igual que 7.

Hubiera sido mejor hacer un:

chat *p=dirname, *d=NULL;
while ( p = strstr(p, 'Cliente') ) {
d = p;
}
if (d) *d = 0;

De este modo encontrarás la última ocurrencia de "Cliente" en tu
cadena y la terminarás justo donde empieza la última ocurrencia. En
caso de que no lo encuentre entonces no borrará nada de la cadena (si
haces d = dirname al principio y eliminas el if final entonces
borrarás el directorio completo en caso de no encontrarlo).
Post by aioritos
strcat(dirname,"Servidor/");
strcat(dirname,Num_Empresa);/*Variable global tipo char* */
Aquí, aunque errorlevel tenga un valor negativo seguirá habiendo
contenido válido en la cadena dirname (aunque quizá hayamos machacado
algún valor de la pila).
Post by aioritos
/*loerrorlevel=strlen(dirname);
dirname[errorlevel]='\0';*/
Aquí volvemos a cortar exactamente por el mismo sitio aunque hayamos
añadido "Servidor/".
Post by aioritos
/*ya tengo direccion para pedir archivos*/
DIR *d=opendir(dirname); /* NULL en caso de error */
¿Has probado un puts(dirname)?

Procura definir la variable fuera junto con las definiciones y luego
hacer un simple:
d=opendir(dirname);

*d es ambiguo y puede significar: escribe el resultado a donde apunte
d tras convertirlo a puntero (siendo de tipo DIR inicialmente).
Post by aioritos
if(d==0)
perror("fa");
¿Has probado un printf para mostrar el valor del puntero?

Procura usar NULL o bien if (!d) para no forzar una conversión de
puntero a entero (si mal no recuerdo sin opciones de optimización se
realiza esa conversión).
Post by aioritos
puts("fin3");
dentry=readdir(d);
puts("fin4");
Posiblemente en d no haya nada "coherente" si lo anterior ha salido
mal. Intenta hacer la prueba y nos cuentas.
Post by aioritos
Gracias.
De nada.
--
Óscar Javier García Baudet
LinaresDigital
http://redstar.linaresdigital.com/
aioritos
2005-07-22 08:33:30 UTC
Permalink
int download_file(int control_id)
{
int data_id,errorlevel;
char listing[BUFFER];
char dirname[255];
FILE *local_file;

struct dirent *dentry;


<<<<<<<<<<
Esta parte he decidido no porner el while que me dijiste, pq
siempre que imprimo el valor de dirname, contiene lo que quiero que
contenga.... asi que de momento lo dejo asi
if(getcwd(dirname, 255)==0)
return FALSE;

/*Tengo que quitar Cliente*/
errorlevel=strlen(dirname);
if(errorlevel > 7){
errorlevel=errorlevel-7;/*strlen("Cliente");*/
dirname[errorlevel]='\0';
}

strcat(dirname,"Servidor/");
strcat(dirname,Num_Empresa);


<<<<<<<<<<<<<<<<<<< BUENO, AUN PONIENDO LA RUTA A
<<<<<<<<<<<<<<<<<<< PELO, SIGUE CASCANDO EL READDIR
/*Ahora d esta definida con las cabeceras arriba...*/
d=opendir(dirname); /* NULL en caso de error */
/*Este cambio no aporta nada de momento*/
if(!d)
perror("fa");
else{
puts("good");
/*si hago un printf de d, casca en el printf....*/
dentry=readdir(d);
}
puts("fin4");
while(dentry != 0){
if(strcmp(dentry->d_name, ".")==0 || strcmp(dentry->d_name,
"..")==0){
dentry=readdir(d);/*Si es . ó .., lee el siguiente anda*/
}


Pero es que creo que no hay nada mal,porque este mismo trozo de codigo
puesto en un main aparte, funciona muy bien sin ningun error ni
warning.

y no entiendo el porque...


Saludos.
J.A. Gutierrez
2005-07-26 08:45:15 UTC
Permalink
aioritos <***@hotmail.com> wrote:

: Pero es que creo que no hay nada mal,porque este mismo trozo de codigo
: puesto en un main aparte, funciona muy bien sin ningun error ni
: warning.

Probablemente habras corrompido la memoria en una fase
anterior del programa.

De todas formas, tratar con directorios de forma portable
es un poco mas complicado que lo que haces. Ver p.e.

http://giga.cps.unizar.es/~spd/src/files-dirs/rdir.c
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
aioritos
2005-07-27 10:27:54 UTC
Permalink
Post by J.A. Gutierrez
Probablemente habras corrompido la memoria en una fase
anterior del programa.
De todas formas, tratar con directorios de forma portable
es un poco mas complicado que lo que haces. Ver p.e.
http://giga.cps.unizar.es/~spd/src/files-dirs/rdir.c
Gracias por responder, pero sigo desde hace varios DIAS igual de
atascado (y me urge mucho), y sin saber si "corrompo la memoria en
alguna fase antes".

En cuanto a lo de tratar directorios de forma portable.. bueno creo que
no es lo que pretendo, solo quiero leer los archivos de una carpeta
para poder mandarlos a un servidor FTP.

El enlace no funciona... pero gracias por el interés
J.A. Gutierrez
2005-07-28 07:23:27 UTC
Permalink
aioritos <***@hotmail.com> wrote:
: Gracias por responder, pero sigo desde hace varios DIAS igual de
: atascado (y me urge mucho), y sin saber si "corrompo la memoria en
: alguna fase antes".

Utiliza alguna libreria que permita detectar corrupcion
de memoria, como p.e. Electric Fence.
<http://perens.com/FreeSoftware/>

El que un trozo de codigo funcione por separado y no lo
haga dentro de otro codigo mas grande es un sintoma tipico
de problemas con el manejo de memoria.

: En cuanto a lo de tratar directorios de forma portable.. bueno creo que
: no es lo que pretendo, solo quiero leer los archivos de una carpeta
: para poder mandarlos a un servidor FTP.

bueno, pero supongo que te gustaria que tu codigo funcione
en la mayor cantidad de sistemas operativos posible, no?

: El enlace no funciona... pero gracias por el interés

Quizas pillaste a la red en un mal momento, ahora lo acabo
de verificar, y funciona.
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
aioritos
2005-08-01 11:56:03 UTC
Permalink
Bueno no se la respuesta a la solucion que acabo de encontrar, pero el
caso es que ya no falla. (y no he tocado el código)

Doy por cerrado el hilo

Victor Sempere
2005-07-22 09:13:35 UTC
Permalink
Puede ser que sea que hayas escrito un carácter no visible y sea por eso.

"aioritos" <***@hotmail.com> escribi� en el mensaje news:***@g14g2000cwa.googlegroups.com...
Hola, tengo un problemilla con el siguiente codigo:


int download_file(int control_id)
{
int data_id,errorlevel;
char listing[BUFFER];
char dirname[255];
FILE *local_file;

struct dirent *dentry;

if(getcwd(dirname, 255)==0)
return FALSE;

/*Tengo que quitar Cliente*/
errorlevel=strlen(dirname);
errorlevel=errorlevel-7;/*strlen("Cliente");*/
dirname[errorlevel]='\0';

strcat(dirname,"Servidor/");
strcat(dirname,Num_Empresa);/*Variable global tipo char* */

/*loerrorlevel=strlen(dirname);
dirname[errorlevel]='\0';*/
/*ya tengo direccion para pedir archivos*/
DIR *d=opendir(dirname); /* NULL en caso de error */
if(d==0)
perror("fa");

puts("fin3");
dentry=readdir(d);
puts("fin4");
while(dentry!=0){
if(strcmp(dentry->d_name, ".")==0 || strcmp(dentry->d_name,
"..")==0){
dentry=readdir(d);/*Si es . ó .., lee el siguiente anda*/
}


A simple vista no parece que este mal; de hecho puesto en un nuevo
fichero fuente funciona!!!

Pero dentro de este codigo no. Alguien tiene mas vista que yo?? Bueno
decir que al bucle while no llega, ni tampoco a imprimir fin4, con lo
que deduzco que el "Sementation fault" se origina en el readdir

Gracias.
aioritos
2005-07-22 09:23:39 UTC
Permalink
No se muy bien a lo que te refieres Victor, supongo que eso se puede
ver con un cat -v, no? El caso es que al hacerlo, no me sale ningun
caracter no imprimible de esos.

Saludos
Loading...