Foros del Web » Programación para mayores de 30 ;) » C/C++ »

Ayuda con DEV-C++. Tema: ficheros

Estas en el tema de Ayuda con DEV-C++. Tema: ficheros en el foro de C/C++ en Foros del Web. primero de todo, me presento ya que es mi primer mensaje. Hola a todos ^^ Segindo: gracias a los que puedan ayudarme. Me explico: Necesito ...
  #1 (permalink)  
Antiguo 01/05/2006, 07:22
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Sonrisa Ayuda con DEV-C++. Tema: ficheros

primero de todo, me presento ya que es mi primer mensaje. Hola a todos ^^
Segindo: gracias a los que puedan ayudarme.
Me explico:
Necesito hacer un programa de una "calculadora de polinomios", pero me han surgido algunas dudas.
1ª-No puedo (o más bien no me sale) cargar ficheros. Además de entrar los polinomios desde teclado, debe de ser posible cargarlos de un archivo de texto o de uno binario, pero me da error.
He hecho la función para cargarlos de texto, pero algo debe de estar mal, la pongo aquí a ver si alguien ve algún error en ella:
Se supone que los polinomios estám hechos por nodos (cada nodo tiene el coeficiente y exponente y apunta al siguiente). Los archivos a leer, tienen un número (exponente, tipo int), un espacio y otro número (coeficiente, tipo float) en cada línea.

int lee_de_texto(char *nombre, p_nodo l)
{FILE *in;
p_node p;
char ex,coe;
in=fopen(nombre,"r");
if(!in) return(-1);
inicializa(l);
while(!feof(in))
{fscanf("%s %s",ex,coe);
p=crea_nodo(1,1);
p->exp=atoi(ex);
p->coef=aof(coe);
p->seg=l->seg;
l->seg=p;
fclose(in);
return(0);
}
if(!p)
{inicializa(l);
fclose(in);
return(1);
}

El tipo de estructura "p_nodo" está bien, porque lo he utilizado en otras partes del programa y funciona. Las funciones "inicializa" y "crea_nodo" también están bien, por eso no las pongo.

No se lo que está mal. ¿Puede ser que en lugar de "fscanf" haya que usar "fgets"? Si es así, decirme que hay que poner dentro del parentesis de "fgets" que esta no se como va ^^U.
¿Podríais decirme también las diferencias que tiene que tener la función para los archivos binarios? (aparte de cambiar "r" por "rb", creo).
gracias por la ayuda.

P.D:Si en algo no me he explicado bien o algo, decirmelo e intentaré ponerlo mejor ^^U.
  #2 (permalink)  
Antiguo 01/05/2006, 09:08
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años, 1 mes
Puntos: 52
Bueno, uno de los errores que deecte fue el siguiente.
Estas usando char coe,ex; Es decir, UN solo caracter.
Y cuando usas fscanf("%s%s....) estas usando cadenas de caraceres.
Tienes de dos, o haces esto:

char coe[5], ex[5];
fscanf(.....)//Igual como lo tenias..

ó

char coe,ex;
fscanf("%c%c", ...);

El promero te lee vasior caracteres hasta el espacio de cada variable y el segundo solo te va a leer un solo caracter por cada variable.

Saludos
  #3 (permalink)  
Antiguo 01/05/2006, 11:31
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
gracias, he hecho el 1º cambio (poner el numero entre corchetes) y funciona (al menos me compila, vamos).
Muchas gracias por todo, ya se donde acudir para la proxima duda ^^
  #4 (permalink)  
Antiguo 06/05/2006, 05:19
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Bueno, he vuelto con más dudas ^^U
Primero de todo, otra función:
He hecho una función para guardar los polinomios en archivos, pero hay una cosa que no se poner, pongo la función:

int guarda(p_node p)
{FILE *in;
char nombre;
p_node aux1=p->seg;
if(aux1!=NULL)
{printf("Di el nombre del archivo donde guardarlo");
scanf("%c",&nombre);
in=fopen("%c",&nombre, "w");
if(in==NULL) return 1;
while(aux1!=NULL)
{fprintf(in, "%d %f.\n",&aux1->exp,&aux1->coef);
aux1=aux1->seg;
}
fclose(in);
return 0;
}
}

La duda en cuestion es:
al compilar pone que hay demasiados argumentos en "fopen". Pues bien, ¿¿como lo hago para, en vez de escribir el nombre del archivo, me lea el que se puso anteriormente (con el scanf)??
Si lo quiero guardar en binario: ¿solo he de ponerr "wb" en vez de "w"??
Una vez se crea el archivo y eso, ¿donde se guarda?
__________________________________________________ _______________

La otra duda es respecto a la funcion anterior (la del post de arriba).
Ya la modifique y compila, pero no me abre archivos, por lo que creo que lo que está mal es la "llamada" a la función que hago en el "main". La pongo:

printf("\nEscrive el nombre del archivo.\n");
scanf("%c",&nombre);
system("pause");
printf("\nEscrive A o B en funcion del polinomio al que quieras asignar los valores del archivo.\n");
fflush(stdin);
if(op=='A' || op=='a')
{A=inicializa();
lee_de_texto(nombre,A);
limpia(A);
}

La opcion B es igual y no la pongo y el mensaje de error por si pone otra letra tampoco (porque no tiene que ver). Como ya puse arriba, la función "inicializa" la he probado en otras funciones y funciona. Con "limpia" pasa lo mismo.
No veo el error o_O
Por si acaso pongo aquí la función corregida:


int lee_de_texto(char *nombre, p_nodo l)
{FILE *in;
p_node p;
char ex[5],coe[20];
in=fopen(nombre,"r");
if(!in) return(-1);
inicializa(l);
while(!feof(in))
{fscanf(in,"%s %s",ex,coe);
p=crea_nodo(1,1);
p->exp=atoi(ex);
p->coef=aof(coe);
p->seg=l->seg;
l->seg=p;
fclose(in);
return(0);
}
if(!p)
{inicializa(l);
fclose(in);
return(1);
}


Gracias por la ayuda y siento poner dudas tan tontas ^^U pero es que acabo de empezar con esto y me lio ^^U

P.D: ¿En el de leer ficheros, el binario es igual pero con "rb" no?

P.P.D: Si hay algun nombre que no cuadra con los declarados, ese no es el fallo, lo que pasa es que el programa me obligan a hacerlo en catalan, y aqui lo he traducido y se me puede haber escapado alguna palabra ^^U

Última edición por mml87; 06/05/2006 a las 05:21 Razón: se me olvido añadir una cosa
  #5 (permalink)  
Antiguo 06/05/2006, 18:17
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
El problema con fopen es que estas usando la como una mescla con scanf,

lo ideal seria declara una variable cadena la cual no es char nombre, sino
char nombre[40];
ya uqe char *nombre; no se podria leer del teclado sin antes recerbar la memoria.(creo).



char nombre[40];
file = fopen(nombre, wb);


con respecto a tu pregunta de donde se guardaria, un fichero sea de texto o binario siempre se guardan en disco, es decir cisco duro si solo usas el nombre se guardara en la misma carpeta de tu ejecutable al menos que uses una direccion valida y diferente.
  #6 (permalink)  
Antiguo 06/05/2006, 22:26
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años, 1 mes
Puntos: 52
Para que saber sobre las funciones de entrada y salida checa las faqs, ahi puse unos posts muy completos.

Saludos
  #7 (permalink)  
Antiguo 07/05/2006, 12:03
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
Gracias ya me compila ^^ pero tengo otra duda xD esto me pasa al guardar. Cuando sale el mensaje de "escribe el nombre del archivo" se cierra la funcion y no me deja escribirlo ^^U
Con la de abrir, me pasa algo parecido, al poner el nombre y pulsar ENTER, se cierra ^^U
  #8 (permalink)  
Antiguo 07/05/2006, 19:22
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
veamos

Enesta ocasion no pones codigo, por tanto es un tanto dificil, comprender a que te refieres con exactitud, pero supongo que te refieres a que el programa se cierra justa despues de el enter.
esto es en main, es decir la funcion main es la que al terminar hace que se cierre la consola, para evitar que se cierre inesperadamente deverias de usar getchar(); justo antes del return 0;

si el problema es que antes de terminar de escribir se cierra o termina la lectura, es probable que estes usando char cadena; en lugar de char cadena[num]; o en numero de caracteres de tu cadena es muy pequeño, en comparacion con la caena a escribir.
  #9 (permalink)  
Antiguo 07/05/2006, 19:24
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
agregar que para leer una cadena no se usa %c sino %s.
ejemplo:

char cadena[50];

scanf("%s", cadena);
printf("%s", cadena);
  #10 (permalink)  
Antiguo 07/05/2006, 20:23
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 22 años, 1 mes
Puntos: 52
Lo repito, eso viene en las faqs muy bien explicado.
Saludos
  #11 (permalink)  
Antiguo 08/05/2006, 04:04
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
NOTA: Ya he habia mirado las FAQs y alguna duda me resolvieron(como la diferencia entre archivo de texto y binario), pero aun asi hay cosas que no me salen. Lo siento, pero es que esto no se me da muy bien ^^U (motivo por el cual al final no me meti en la carrera de informatica xD).

La funcion de guardar ya me funciona, parece que al poner %s en vez de %c y getchar() funciona bien ^^ gracias.
Pero ahora bien, he modificado la de leer texto pq me di cuenta de que habia una cosa mal (al assignar el valor, no al abrir el fichero, asi que lo de que no lo abria no es consecuencia de ese error, creo) y he puesto el getchar() por si acaso.

La pongo:

int lee_de_texto(char *nombre, p_nodo l)
{FILE *in;
p_node p,aux1;
char ex[5],coe[20];
in=fopen(nombre,"r");
if(!in) return(-1);
inicializa(l);
aux1=l->seg;
while(!feof(in))
{fscanf(in,"%s %s",ex,coe);
p=crea_nodo(1,1);
p->exp=atoi(ex);
p->coef=aof(coe);
p->seg=aux1->seg;
aux1->seg=p;
aux1=aux1->seg;
fclose(in);
getchar();
return(0);
}
if(!p)
{inicializa(l);
fclose(in);
return(1);
}
}

Pongo la parte donde la utilizo:
esta dentro del main() en un menu.

case'b':{printf("\nSi cargas un polinomio en uno existente, el anterior se perdera.\n Si quieres continuar escrive 0, si quieres salir de esta opcion escrive 1\n");
scanf("%d",&can);
if(can==0)
{printf("\nEscrive el nombre del archivo.\n");
scanf("%s",&nombre);
system("pause");
printf("\nEscrive A o B en funcion del polinomio al que quieras asignar el valor del archivo.\n");
fflush(stdin);
scanf("%c",&op);
if(op=='A' || op=='a')
{A=inicialitza();
llee_de_texto(nombre,A);
limpia(A);
entrarA=1;
}
else if(op=='B' || op=='b')
{B=inicialitza();
llee_de_texto(nombre,B);
limpia(B);
entrarB=1;
}

else printf("\nPon la lletra A o B, no importa si es majúscula o minúscula.");
}
};
break;

Las variables que uso para las diferentes opciones (can, op...) estan declaradas. Y las funciones que no estan aqui las he probado y funcionan.
Tal y como esta ahora, llega correctamente hasta el (printf("\nPon la lletra A o B, no importa si es majúscula o minúscula.");). Despues de seleccionarla y pulsar ENTER me sale la ventana de "windows a detectado un error y debe cerrar el programa ".
Ese es el unico error que me da de momento. Gracias por la ayuda.
  #12 (permalink)  
Antiguo 08/05/2006, 18:23
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
Veamos

Mira probablemante el problema sea con los punteros, por falta de recerba como la variable nombre, la cual no veo como es que esta declarada,

si puedes escribir todo tu codigo, lo probare para resolver esto de una vez.

Saludos.
  #13 (permalink)  
Antiguo 09/05/2006, 11:01
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
He hecho algunas modificaciones a la funcion "leer" y parece que si que lee, pero la ultima fila del archivo la lee dos veces (me hace 2 nodos con ese valor). La pongo:

int lee_de_texto(char *nombre, p_nodo l)
{FILE *in;
p_nodo p,aux1;
char ex[5],coe[20];
in=fopen(nombre,"r");
if(!in) return(-1);
inicializa(l);
aux1=l;
while(!feof(in))
{fscanf(in,"%s %s",ex,coe);
p=crea_nodo(1,1);
p->exp=strtod(ex,0);
p->coef=strtod(coe,0);
p->seg=aux1->seg;
aux1->seg=p;
aux1=aux1->seg;
}
if(p)
{fclose(in);
getchar();
return(0);
}
else
{inicializa(l);
fclose(in);
return(1);
}
}

Del tema de ficheros, esto es lo único que me queda (y hacer lo mismo para binario, pero eso es sólo modificar un par de cosas ^^U). Gracias por vuestra ayuda, sois los mejores ^^
  #14 (permalink)  
Antiguo 10/05/2006, 11:43
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años, 8 meses
Puntos: 2
hay unas dudas que me quedan, pero es por falta de conocimiento de tu codigo, espero que todo este bien, como el manejar el p_nodo p como un puntero a nodo, es probable que tengas un typedef, por que el parametro no es un puntero.

en realidad no es necesario el getchar() en ese nivel. te lo mecione para el caso de main, para que esta funcion no terminara antes de mostrar los datos, pero creo que usaste el system("pause"); es mejor asi.

El problema de doble lectura del ultimo nodo es por la forma en que lees tus ficheros:

while(!feof(in))
{fscanf(in,"%s %s",ex,coe);
p=crea_nodo(1,1);
p->exp=strtod(ex,0);
p->coef=strtod(coe,0);
p->seg=aux1->seg;
aux1->seg=p;
aux1=aux1->seg;
}

cuando lees el ultimo nodo, el cursor de lecctura se pocisiona listo para leer el EOF, por tanto al usar feof(in) aun no te da true, pues aun no se lee el final, por tanto al leer el EOF, se guardan en tus nodos los datos leidos anteriormente.

yo lo he cambiado a esta forma:

while(fscanf(in,"%s %s",ex,coe) != EOF)
{
}

intentalo y me cuentas.
  #15 (permalink)  
Antiguo 10/05/2006, 12:06
 
Fecha de Ingreso: mayo-2006
Mensajes: 11
Antigüedad: 18 años, 8 meses
Puntos: 0
He probado eso y no funciona ^^U de esa forma que me dices sólo me imprime la 1ª línea ^^U
Pero igualmente, lo he podido corregir. He modificado la función "guardar" y en el bucle, he hecho que llegue a un nodo menos y el último lo guardo sin "\n", así no pone una línea vacía al acabar y el de leer no se lía ^^U
De todas maneras muchas gracias por vuestra ayuda, no se que hubiese sido de mí sin vosotros ^^
Me falta añadir las mismas funciones en binario, si por un casual tuviese errores ya os avisaré, aunque creo que en esto me apaño con las FAQs ^^
Saludos y gracias de nuevo.
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 2 personas (incluyéndote)




La zona horaria es GMT -6. Ahora son las 18:05.