Páginas: [1]
|
 |
|
Autor
|
Tema: Problema con funcion (Leído 253 veces)
|
Leber
Desconectado
Mensajes: 249
"Las estrellas se apagan..."
|
Buenas, estoy reprogramando una agenda que hice para mejorarla, pero en una funcion tengo un problema de los gordos y no se por que, pero me sale mi viejo amigo "segmentation fault". Primero les dejo el codigo que llevo hecho, y despues la funcion en concreto: Codigo entero(faltan aun funciones y demas): #include <stdio.h> #include <stdlib.h> #include <string.h>
struct datos{
int rec; char nombre[30]; char apellidos[50]; char dir[60]; int telefono; int movil;
};
struct datos *agenda; FILE *fi;
void visualizar(char *fichero); void insertar(char *fichero); void usage(char *prog); void menu(char *fichero);
int main(int argc, char **argv) { char *fichero=(argc>1) ? argv[1] : "agenda.dat"; char *prog=argv[0]; int i;
if(argc>2) usage(prog);
else if(argc==2) { for(i=strlen(fichero)-1;i>=strlen(fichero)-1;i--) if(argv[1][i]!='t') usage(prog); else menu(fichero); }
exit(0); } void menu(char *fichero) {
char o;
fprintf(stdout,"\n\t1:Visualizar registros\n\t2:Insertar registros\n\t3:Buscar registros\n\t4:Salir\n"); do{ printf("\nOpcion: "); o=getchar(); while(getchar()!='\n') continue; switch(o) { case '1': printf("Visua\n"); visualizar(fichero); break; case '2': printf("In\n"); insertar(fichero); break; case '3': printf("Buscar registros\n"); break; case '4': exit(0); break; default: printf("opcion %c incorrecta\n",o); } }while(o<1 || o>4);
}
void insertar(char *fichero) { extern struct datos *agenda; extern FILE *fi; static registro=1; char movil[15]; char telefono[20];
fi=fopen(fichero,"a+b"); registro++;
if(fi==NULL) { perror(fichero); exit(-1); free(agenda); }
agenda=(struct datos *)malloc(sizeof(struct datos));
agenda->rec=registro; printf("Nombre: "); gets(agenda->nombre); printf("Apellido: "); gets(agenda->apellidos); printf("Direccion: "); gets(agenda->dir); printf("Telefono: "); gets(telefono); agenda->telefono=atoi(telefono); printf("Movil: "); gets(movil); agenda->movil=atoi(movil);
fwrite(agenda,sizeof(struct datos),1,fi); free(agenda);
menu(fichero);
}
void visualizar(char *fichero) { int i=0; char texto[80]; extern FILE *fi; extern struct datos *agenda;
if((fi=fopen(fichero,"rb"))==NULL) {
perror(fichero); menu(fichero); } while(!feof(fi)){ i++; fseek(fi,i*sizeof(struct datos),SEEK_SET); fread(agenda,sizeof(struct datos),1,fi); printf("%d\n %s\n %s\n %s\n %d\n %d\n",agenda->rec,agenda->nombre,agenda->dir,agenda->telefono,agenda->movil); } fclose(fi); }
void usage(char *prog) {
fprintf(stderr,"uso:\n%s: [fichero]\n",prog); fprintf(stderr,"Si no se especifica fichero, se usara \"agenda.dat\"\nSi por el contrario se especifica fichero, este debe ser \".dat\"\n\n"); exit(-1);
}
Funcion en concreto: void visualizar(char *fichero) { int i=0; char texto[80]; extern FILE *fi; extern struct datos *agenda;
if((fi=fopen(fichero,"rb"))==NULL) {
perror(fichero); menu(fichero); } while(!feof(fi)){ i++; fseek(fi,i*sizeof(struct datos),SEEK_SET); fread(agenda,sizeof(struct datos),1,fi); printf("%d\n %s\n %s\n %s\n %d\n %d\n",agenda->rec,agenda->nombre,agenda->dir,agenda->telefono,agenda->movil); } fclose(fi); } Gracias de antemano, un saludo
|
|
|
|
|
En línea
|
"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
|
|
|
Leber
Desconectado
Mensajes: 249
"Las estrellas se apagan..."
|
una mano ? Bueno por si les da pereza leer todo el codigo, solo pondre la funcion que escribe, y la que lee. A ver si entre todos vemos el problema ya que yo no se lo veo... Funcion que escribe: void insertar(char *fichero) { extern struct datos *agenda; extern FILE *fi; static registro=1; char movil[15]; char telefono[20];
fi=fopen(fichero,"a+b"); registro++;
if(fi==NULL) { perror(fichero); exit(-1); free(agenda); }
agenda=(struct datos *)malloc(sizeof(struct datos));
agenda->rec=registro; printf("Nombre: "); fgets(agenda->nombre,30,stdin); agenda->nombre[strlen(agenda->nombre)-1]=0;
printf("Apellido: "); fgets(agenda->apellidos,50,stdin); agenda->apellidos[strlen(agenda->apellidos)-1]=0;
printf("Direccion: "); fgets(agenda->dir,60,stdin); agenda->dir[strlen(agenda->dir)-1]=0;
printf("Telefono: "); fgets(telefono,20,stdin); telefono[strlen(telefono)-1]=0; agenda->telefono=atoi(telefono);
printf("Movil: "); fgets(movil,15,stdin); movil[strlen(movil)-1]=0; agenda->movil=atoi(movil);
fprintf(stdout,"Nombre:%s\nApellidos:%s\nDireccion:%s\nTelefono:%d\nMovil:%d\n",agenda->nombre,agenda->apellidos,agenda->dir,agenda->telefono,agenda->movil);
fwrite(&agenda,sizeof(struct datos),1,fi); free(agenda);
menu(fichero);
} Funcion que lee void visualizar(char *fichero) { int i=0; char texto[80]; extern FILE *fi; extern struct datos *agenda;
if((fi=fopen(fichero,"rb"))==NULL) {
perror(fichero); menu(fichero); } while(fread(agenda,sizeof(struct datos),1,fi)) { printf("%d\n %s\n %s\n %s\n %d\n %d\n",agenda->rec,agenda->nombre,agenda->dir,agenda->telefono,agenda->movil); } fclose(fi); } Gracias de antemano
|
|
|
|
|
En línea
|
"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
|
|
|
project 2501
Desconectado
Mensajes: 137
|
Lo primero decir que no he probado el codigo y te voy a decir las cosas segun las veo. Hay una cosa que puede liar un poco al compilador y al programa entero, y es que primero declaras las variables "agenda" y "fi", es decir la estructura y el fichero, y luego en cada funcion la vuelves a declarar con el mismo nombre. Hay puede que el programa se haga un lio. Otra cosa que te puede fallas es a la hora de los telefonos. Te explico, en una variable "int" puedes guardar un numero hasta el 65000 y pico, y un numero de telefono al menos tiene 9 cifras (eso en españa claro en otros sitios incluso mas) y al pasar un numero de 9 cifras a una variable int te puede hacer cosas raras. Cuando guardes en el fichero, abrelo con un editor de texto y mira que los datos esten en el. De esta manera compruebas que no tengas el error al escribir, porque si tienes algo no te mostrara todos los datos o algo asi, y entonces igual no casca al escribir, pero si casca al leerlo. Otra cosa que deberias hacer es poner puntos de ruptura y ver que los datos se guardan en la estructura correctamente, tanto en el momento de introducirlos por teclado como en el momento de leerlos. Y ahora mismo no se me ocurre mucho mas. Espero haberte sido de ayuda 
|
|
|
|
|
En línea
|
¿Y a dónde va el recién nacido desde aquí? La red es vasta e infinita
|
|
|
Leber
Desconectado
Mensajes: 249
"Las estrellas se apagan..."
|
Buenas, gracias por responder, te explico:
No declaro las variables 2 veces, sino que le digo que esas 2 variables son externas al programa, ya que sino, no me las coge, porque estan fuera de la funcion.
En cuanto a escribirlo en la estructura, si que lo escribe, ya que luego lo miro con printf, y estan los datos escritos correctamente.
Sin embargo, al leer, o no me muestra nada, o me aparece el "segmentation fault".Al abrir el editor de texto, me dice que el fichero es binario, y me muestra los datos y algo de basura como simbolitos extraños.
Saludos
|
|
|
|
|
En línea
|
"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
|
|
|
project 2501
Desconectado
Mensajes: 137
|
al final has conseguido que me ponga a revisar todo el codigo xD Bueno he cambiado alguanas cosas para ponerlas a mi gusto (sino programo de muy mala gana, jejejeje). Pero bueno basicamente es lo mismo. Los cambios son en la funcion visulizar que era la que tu decias de principio. Pero como he cambiado mas cosas pues te lo pongo entero, por si acaso no te funciona solo con la funcion. Si tienes cualquier duda de porque hice una cosa u otra, pues preguntas  #include <stdio.h> #include <stdlib.h> #include <string.h> struct datos{ int rec; char nombre[30]; char apellidos[50]; char dir[60]; int telefono; int movil; }; void visualizar(char *fichero); void insertar(char *fichero); void usage(char *prog); void menu(char *fichero); int main(int argc, char **argv) { char *fichero=(argc>1) ? argv[1] : "agenda.dat"; char *prog=argv[0]; int i; if(argc>2) usage(prog); else if(argc==2) { for(i=strlen(fichero)-1;i>=strlen(fichero)-1;i--) if(argv[1][i]!='t') usage(prog); else menu(fichero); } exit(0); } void menu(char *fichero) { char o; fprintf(stdout,"\n\t1:Visualizar registros\n\t2:Insertar registros\n\t3:Buscar registros\n\t4:Salir\n"); do { printf("\nOpcion: "); o=getchar(); while(getchar()!='\n') continue; switch(o) { case '1': printf("Visua\n"); visualizar(fichero); break; case '2': printf("In\n"); insertar(fichero); break; case '3': printf("Buscar registros\n"); break; case '4': exit(0); break; default: printf("opcion %c incorrecta\n",o); } }while(o<1 || o>4); } void insertar(char *fichero) { struct datos *agen; FILE *fi; static registro=1; char movil[15]; char telefono[20]; fi=fopen(fichero,"w"); registro++; if(fi==NULL) { perror(fichero); free(&agen); exit(-1); } agen=(struct datos *)malloc(sizeof(struct datos)); agen->rec=registro; printf("Nombre: "); gets(agen->nombre); printf("Apellido: "); gets(agen->apellidos); printf("Direccion: "); gets(agen->dir); printf("Telefono: "); gets(telefono); agen->telefono=atoi(telefono); printf("Movil: "); gets(movil); agen->movil=atoi(movil); fwrite(agen,sizeof(struct datos),1,fi); free(agen); fclose(fi); menu(fichero); } void visualizar(char *fichero) { int i=0; char texto[80]; FILE *fi; struct datos age; if((fi=fopen(fichero,"rb"))==NULL) { perror(fichero); } else { while(fread(&age,sizeof(struct datos),1,fi) != 0) { printf("nombre: %s\napellidos: %s\ndireccion: %s\ntelefono: %d\nmovil: %d\n",age.nombre,age.apellidos,age.dir,age.telefono,age.movil); } fclose(fi); } } void usage(char *prog) { fprintf(stderr,"uso:\n%s: [fichero]\n",prog); fprintf(stderr,"Si no se especifica fichero, se usara \"agenda.dat\"\nSi por el contrario se especifica fichero, este debe ser \".dat\"\n\n"); exit(-1); }
|
|
|
|
|
En línea
|
¿Y a dónde va el recién nacido desde aquí? La red es vasta e infinita
|
|
|
Leber
Desconectado
Mensajes: 249
"Las estrellas se apagan..."
|
Pues sigue sin funcionarme, cuando le doy a la opcion visualizar no me aparece nada. Y tengo 2 preguntas: 1: if(fi==NULL) { perror(fichero); exit(-1); free(&agenda); } Porque en esta parte haces free como si liberaras a donde apunta agenda, y en el free de abajo le quitas el &. y 2: Porque en una funcion declaras la estructura como un puntero, y en la otra no. Ya esta, y eso, que el codigo no da ningun error en tiempo de ejecucion, solo que no muestra nada al darle a visualizar, y cuando le doy a un editor de texto para ver que ha escrito, me sale algun dato, y mucho basura como simbolitos. Gracias por el tiempo
|
|
|
|
|
En línea
|
"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
|
|
|
project 2501
Desconectado
Mensajes: 137
|
lo del free, fallo mio, jejejeje. Aun asi, al free que has puesto como ejemplo (que es el que esta mal) el programa no llega nunca, porque si hay error has puesto el exit(-1); delante del free asi que saldria del programa antes de liberar. Respecto a lo de punteros o no, pues segun como voy haciendo las cosas hay veces que lo hago con punteros y otras no, no hay ninguna razon en especial. A mi el programa me funciona bien. Te digo lo que hago porque igual lo hacemos diferente o algo. gcc <nombrePrograma> -o agenda ./agenda agenda.dat y con eso a me chuta perfectamente. Si no pongo argumentos el programa no funciona, eso ya no lo he mirado, eh Suerte. 
|
|
|
|
|
En línea
|
¿Y a dónde va el recién nacido desde aquí? La red es vasta e infinita
|
|
|
Leber
Desconectado
Mensajes: 249
"Las estrellas se apagan..."
|
Jaja, no se si calarme fuego o darme de cabeza contra la mesa. En mi aplicacion, habia una linea mal:
printf("%s %s %s %d %d\n",agenda->nombre,agenda->dir,agenda->telefono,agenda->movil);
Faltaba agenda->apellidos, y por eso causaba la violacion del segmento, en fin, que fallos como estos te hagan perder tanto tiempo... hay que ver.
En fin, almenos tu codigo me sirvio para darme cuenta de este fallito jaja.
Muchas gracias y saludos
|
|
|
|
|
En línea
|
"Solo los tontos carecen de preucupaciones." Johann Wolfgang Goethe
|
|
|
project 2501
Desconectado
Mensajes: 137
|
Joer, yo tampoco me habia dado cuenta, jejeje.
Que manera de darle vueltas, jejejeje.
|
|
|
|
|
En línea
|
¿Y a dónde va el recién nacido desde aquí? La red es vasta e infinita
|
|
|
|
Páginas: [1]
|
|
|
|