Consultas, desarrollo de programas y petición de presupuestos:

jueves, 12 de julio de 2012

C: trabajar con directorios

Programa en C para leer datos de un directorio:
¿como sabemos que cabecera necesitamos? Pues si usamos una funcion que no este en la cabecera dara un error, y tendremos que buscar en el man esa funcion para ver que include hace falta
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h> // siempre lo incluimos
#include <stdlib.h>
#include <time.h>

void VerResultado(char *, struct stat *); // recibe una estructura puntero tipo stat.

int main(int argc, char *argv[]) { // char **argv es igual que char *arg[]
DIR *pdir; // declarao un puntero pdir que es del tipo DIR (al igual que el tipo FILE, que manejaba fichero, el DIR, maneja directorios
char *nomfich;
char nomcomp[255];
struct stat st; //variable creada llamada st, del tipo struct star. Esta variable nos sirve para conocer los datos de un fichero.
struct dirent *dp; // puntero llamado dp, del tipo struct dirent, esta variable nos sirve para conocer informacion sobre una entrada (subdirectorio, fichero) de un directorio

if (argc != 2) { // si no tengo dos argumentos (nombre del programa y directorio), da error.
fprintf(stderr, "%s: Uso: %s nombre_directorio\n", argv[0], argv[0]);
exit(-1); // no ponemos 0 porque hay un fallo.
}

pdir = opendir(argv[1]); // funcion opendir: abre un directorio como si fuese un fichero.
if (pdir == NULL) { // si no existe el directorio....
perror(argv[0]); // funcion perror(): te va a devolver el mensaje actual de error que ha generado tu programa. Es el mismo que te daria un comando del sistema cuando da ese error. En perror estan todo los posibles mensajes del sistema. Se le indica el nombre de mi programa argv[0], para que salga ese.
exit(-1); // no ponemos 0 porque hay un fallo.
}

dp = readdir(pdir); // funcion readdir(): lee una entrada del directorio. “dp”, contendrá la primera linea del diretorio
while (dp != NULL) { //cuando devuelvo NULL, salgo del while, ya no hay mas datos.
sprintf(nomcomp, "%s/%s", argv[1], dp->d_name);
//sprintf guarda la variable lo que escribe con el formato “%s%s”.
// dp->d_name: la estructura tipo dp contiene un dato llamado d_name. Cuando son variables normales dentro las estructuras los datos los sacamos con “.”, (ejemplo: tablaresultado.nombre). Pero cuando se trata de un dato tipo puntero dentro de esa estructura (d_name), se hace con “->”.
nomfich = dp->d_name; // nomfich= le paso el puntero dp->d_name, copio el nombre a esta variable

if (stat(nomcomp, &st) < 0) { // la funcion star(fichero,&st), pasa la informacion de ese fichero (y necesita la ruta completa de donde este) y la informacion que ha obtenido la guarda en la &st ¿que significa el & delante de la variable st), representa la direccion de memoria donde se almacena esa variable, y que la meta hay (al reves que un puntero), ya tengo un sitio reservado y la meto hay.
// stat devuelve un numero, diciendo que si lo ha podido hacer o no. Si da “0” ha funcionado, y si da “<0” no ha funcionado
perror(nomcomp); // mostramos el error que se ha producido.
} else {
VerResultado(nomfich, &st); // mostramos la información
}
dp = readdir(pdir); //vuelvo a leer el siguiente dato que haya directorio
}
closedir(pdir); // cierre del directorio.

Return 0; // devuelvo que todo ha ido bien.
}


void VerResultado(char *nomfich, struct stat *st) {
// le paso el puntero del nombre del fichero, y ahora le paso la direccion de memoria donde esta almacenada el sitio st. Ver man 2 stat
// ultimo modificacion: cambio de permisos, nombre del fichero
// ultimo cambio: cambio del contenido interior del fichero
struct tm *t; // ver man gmtime
t = gmtime(&st->st_mtime); // gmtime: rellenar la estrutura t, basandose en una de las partes (st_mtime) de la estructura st, como es un puntero uso “->”, y con & le digo el sitio donde lo cojo.

printf("%-20s %8ld bytes %02d/%02d/%4d %02d:%02d:%02d\n",
nomfich,
st->st_size,
t->tm_mday,
t->tm_mon + 1,
t->tm_year + 1900,
t->tm_hour,
t->tm_min,
t->tm_sec);
//t->tm_mon + 1, /empieza a enumerar los meses con 0, le tengo que sumar uno
//t->tm_year + 1900, da la fecha y empiezo a contar desde 1900

}









No hay comentarios:

Publicar un comentario