Ver la versión completa : listado de ficheros
Llevo toda la tarde dandole vueltas a lo mismo y nada no doy con la tecla :canon2:
De mientras que no tengo la consola, he estado intentando hacer un frontend para el smsplus. Como el de snes2x que es "skinable". Y me he puesto a hacerlo sobre todo porque sabia que me iba a encontrar con este problema...grrr
Resulta que necesito obtener un listado de todos los archivos y carpetas en un directorio, y filtrar solo los que tengan extension "sms" y "gg"
Pero lo más que he llegado a encontrar es la función scandir, que mete en un array todo el contenido de un directorio y devuelve el numero de elementos.
Hasta aquí parece todo facil pero me hago un lio manejando cadenas y tal que al final siempre me acaba saliendo un bonito "Segmentation fault" :shock:
Todo esto lo he estado mirando en la documentación de la GNU Libc, que o yo soy muy torpe o no se yo, pero no saco nada en claro de ahi
¿alguien con experiencia me da algun consejillo? :confused:
Intenta averiguar qué es lo que peta, que Segmentation Fault es un error muy genérico (si no me equivoco, significa que accedes a memoria no reservada).
Y bueno, por si no lo sabes, las cadenas de caracteres en C han de acabar en \0, con lo que la medida del array ha de ser como mínimo el número de caracteres esperados, más uno. Que no sea eso...
Si quieres le puedo hechar un vistazo. Me puedes agregar al messenger o enviarme por mail el código entero o el que crees que te peta y le hecho un vistazo. Ya le heché una ayudita a AOJ con sus prácticas y si puedo con esto también te miro que puede ser ;)
Intenta averiguar qué es lo que peta, que Segmentation Fault es un error muy genérico (si no me equivoco, significa que accedes a memoria no reservada).
Y bueno, por si no lo sabes, las cadenas de caracteres en C han de acabar en \0, con lo que la medida del array ha de ser como mínimo el número de caracteres esperados, más uno. Que no sea eso...
Sip, el error tiene toda la pinta de que intenta acceder a una posición que esta fuera de un array y por eso peta. Quizás se le escapa en algún bucle que da alguna vuelta de más o algo por el estilo ...
Los segmentation fault eran por salirme del array y/o trastear con punteros, direcciones, etc.. lo se porque me salían cuando estaba experimentando con los parámetros de las funciones :D
La cuestion es que no se como **** hacer para filtrar los archivos que tengan "sms" al final. Esta claro que con operaciones de cadenas, ir comparando, pero no doy con ninguna función de la libreria estándar que lo haga, o bien soy muy torpe ^_^
Ahora mismo tengo este codigo, sacado de ejemplos que he encontrado por la web:
#include <stdio.h>
#include <dirent.h>
int main()
{
int n;;
struct dirent **namelist;
n=scandir(".",&namelist,0,alphasort); //<< Almacena la lista de archivos en la estructura namelist y devuelve el numero de elementos en "n"
if (n < 0)
perror("scandir");
else {
while(n--) {
printf("%s\n",namelist[n]->d_name); //<< muestra el nombre de archivo del elemento "n"
free(namelist[n]);
}
free(namelist);
}
return 0;
}
El nombre de cada archivo lo tengo en namelist[n]->d_name, asi que solo tengo que ir mirando cual tiene "sms" y almacenarlo en un array de cadenas aparte para ya usarlo luego.. pero comoo comparoo
Ahora mismo estaba mirando en la documentacion de la glibc que vienen bastantes funciones de comparacion de cadenas pero no doy con la buena.
Bueno y ahora que lo pienso, como distingo cuales son carpetas :confused:
A lo mejor hay una forma mas sencilla y me estoy comiendo la cabeza para nada ^_^ las cosas de ser "newbie"
Puck2099
26/11/2005, 02:19
A ver, te cuento lo que se me ha ocurrido, por si te es de ayuda.
Podrías ir mirando caracter a caracter en el nombre de cada fichero hasta encontrar la posición donde esté el punto anterior a la extensión. Luego ya solo tienes que mirar los 3 caracteres siguientes y si son "sms" pues añades ese fichero a la lista que tengas.
En código (no probado):
while (i<LONG_MAX && !encontrado) {
if (nombre_fichero[i] == '.') {
if (nombre_fichero[i+1] == 's' && nombre_fichero[i+2] == 'm' && nombre_fichero[i+3] == 's') {
encontrado = 1; // Este es un fichero válido, añadirlo a la lista
}
}
i++;
}
Dime si te vale :)
Saludos
while (i<LONG_MAX && !encontrado) {
if (nombre_fichero[i] == '.') {
if (nombre_fichero[i+1] == 's' && nombre_fichero[i+2] == 'm' && nombre_fichero[i+3] == 's') {
encontrado = 1; // Este es un fichero válido, añadirlo a la lista
}
}
i++;
}
Dime si te vale :)
Saludos
Pues sí, yo también haría eso mismo.
YAAAAAAAAAAAAAA
Muchisimas gracias a los tres.
Puck2099 al final ha sido como tu has dicho pero variandolo un poco. Al final ha sido mas simple de lo que yo pensaba :)
while(n--) {
if(namelist[n]->d_name[(strlen(namelist[n]->d_name))-1] == 's' && namelist[n]->d_name[(strlen(namelist[n]->d_name))-2] == 'm' && namelist[n]->d_name[(strlen(namelist[n]->d_name))-3] == 's') printf("%s\n",namelist[n]->d_name); //<< muestra el nombre de archivo del elemento "n"
free(namelist[n]);
}
simplemente comparo el final de la cadena, teniendo en cuenta que cadena es strlen(cadena) pues el ultimo caracter sera strlen(cadena)-1
:) :)
Que felicidad entra cuando se da con la tecla
Muchas gracias por la ayuda :)
while(n--)
{
if(strstr(".sms",namelist[n]->d_name) != NULL)
printf("%s\n",namelist[n]->d_name);
free(namelist[n]);
}
Eso tambien te puede servir, aunque hay que refinarlo un poco.
Por ejemplo tu codigo se cae si tienes algo como "xxxsms" (sin extension)
Y el mio se cae si hay algo como "xxx.sms.xxx"
while(n--)
{
if(strstr(".sms",namelist[n]->d_name) != NULL)
printf("%s\n",namelist[n]->d_name);
free(namelist[n]);
}
Eso tambien te puede servir, aunque hay que refinarlo un poco.
Por ejemplo tu codigo se cae si tienes algo como "xxxsms" (sin extension)
Y el mio se cae si hay algo como "xxx.sms.xxx"
Basta con añadirle otra comprobación más, la del punto, a mi codigo :p
Ahora donde me he atrancado es en como voy metiendo dinamicamente en un array todos los resultados "buenos". Creo que habría que reservar memoria dinamicamente o cosas de esas no? Mi libro de programacion en C esta a 50 kilometros de aqui :(
Es cierto, con agregarle una comprobacion mas lo haces, pero ten en cuenta que eso que estas haciendo es ineficiente.
En cada comprobacion estarias recorriendo el array 4 veces (uno por cada strlen).
En fin, te recomiendo que programes una lista simple para ir guardando los nombres.
johnnypalmera
26/11/2005, 03:40
efegea, en vez de crear otro array y rellenarlo dinamicamente, quédate en una lista simple las posiciones "buenas" y muestra solo eso por pantalla. Te evitarás muchos líos y muchos segmentation faults, creeme.
Es cierto, con agregarle una comprobacion mas lo haces, pero ten en cuenta que eso que estas haciendo es ineficiente.
Bueno solo es para cargar roms, no pasa nada si es poco eficiente (aunque tal vez tenga problemas con "alex.kid.sms")
Por cierto animo a estos ports, i una pregunta, es muy dificil compilar la libreria sdl para la gpx2? (yo no sabira por donde empezar)
Bueno solo es para cargar roms, no pasa nada si es poco eficiente (aunque tal vez tenga problemas con "alex.kid.sms")
Por cierto animo a estos ports, i una pregunta, es muy dificil compilar la libreria sdl para la gpx2? (yo no sabira por donde empezar)
Me temo que estoy en desacuerdo contigo mi amigo Logann, es importante siempre buscar la mayor eficiencia del programa, aun en las cosas que parecen mas triviales.
Es un buen ejercicio mental y una de las buenas costumbres que todo programador debe tener.
Veo que llego un poco tarde, pero por si las moscas os pongo una referencia a mi librería folder.h pensada para extraer nombres de archivos de la SMC de la GP32. No debería de ser muy complicado adaptarla a la GP2X.
Lo interesante de la función es que permite comodines como en el DOS.
Aquí teneis la dirección: http://www.nekanium.com/gp32/cLibraries.htm#Folder
NoobLuck
26/11/2005, 09:18
int scandir(const char *dir, struct dirent ***namelist,
int (*select)(const struct dirent *),
int (*compar)(const struct dirent **, const struct dirent **));
int alphasort(const struct dirent **a, const struct dirent **b);
DESCRIPCIÓN
La función scandir() rastrea el directorio dir, llamando select() en
cada entrada de directorio. Las entradas para las que select() devuelve
un valor distinto de cero se almacenan en cadenas (strings) reservadas
vía malloc(), ordenadas usando qsort() con la función de comparación
compar(), y puestas en la matriz namelist que está reservada vía mal-
loc(). Si select es NULL, se seleccionan todas las entradas.
Si sigues las instrucciones, tienes que implementar una funcion select:
int my_select(const struct dirent *this_direntry){
char *aux=NULL;
aux = rindex( this_direntry->d_name, '.');
if ((aux != NULL) && !strcmp(aux, extension)) return 1;
else return 0;
}
Ademas la funcion rindex devuelve la posición de la última aparición de un caracter.
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.