Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Mr.Blue en 4 Mayo 2010, 04:31 am



Título: Manejo de Archivos duda!
Publicado por: Mr.Blue en 4 Mayo 2010, 04:31 am
Bueno les comento, tengo una duda al usar archivos,  mi idea es generar un archivo y que en este se puedan intresar datos el tema es que cada ves que se ingresan nuevos datos los datos anteriores se borran reemplazandolos por los nuevos datos, como puedo hacer para q esto no pase? osea que mantenga estos datos y en un renglon aparte escriba estos nuevos datos.

Otra pregunta tmb que me esta pasando es que al guardar estos datos ademas de la imformacion que ingreso tambien se guardan caracteres que no fueron ingresados como por ejemplo, letras o simbolos %, $ no se si es porq faltaria limpiar algo o no,
en mi ejercicio de ejemplo utilizo una structura la cual contine cadenas de caracteres y a estas las ingreso todo con gets, ya q no puedo  usar printf ya que le una palabra en ves de una palabra.

Código
  1.  
  2. struct datos {
  3. char nombre [15];// nombre del usuario
  4. char pass [6];//password del usuario
  5. int main()
  6. datos regin;
  7. FILE *fichero;
  8. FILE *pf; // apunta al archivo
  9.  
  10.  
  11. pf=fopen ("C:\\users.txt","wb");
  12.  
  13. if (pf==NULL)
  14.  {
  15. printf ("ERROR DE LECTURA");
  16. getch();
  17. exit(1);
  18.  }
  19.  
  20.  while (i!=0) {
  21.  
  22. printf ("\nINGRESE NOMBRE DE USUARIO:");
  23. gets (regin.nombre);
  24.  
  25. printf ("\nINGRESE PASSWORD:");
  26. gets (regin.pass);
  27.  

una parrte del codigo en donde se muestra la structura, la apertura del archivo el ingreso de datos por si es de ayuda.


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 4 Mayo 2010, 04:35 am
Abrí el archivo en modo a (Append)

Saludos


Título: Re: Manejo de Archivos duda!
Publicado por: Mr.Blue en 4 Mayo 2010, 05:30 am
ajam ahi ta arreglado gracias
y por el tema de que los datos entrancon basura?


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 4 Mayo 2010, 05:49 am
Ni idea porque no se como estas implementando los ciclos, las lecturas, las escrituras, ni los tipos de datos. El código que pusiste fue de ejemplo (y por cierto con algunos errores) y no indica lo suficiente como para responderte eso.
Pone el código completo y lo vemos (pero si es demasiado largo, prueba depurandolo vos mismo)

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: taul en 4 Mayo 2010, 08:03 am
mmm el code esta bastante mal escrito..pero te felicito por empezar con C es lo mas grande q hay "para mi"

algo asi estaria mejor escrito:

Código:
#include <stdio.h>
#include <stdlib.h>

struct datos { //extructura
char nombre [15];// nombre del usuario
char pass [6];//password del usuario
}regin;

int i=0;

int main(){
FILE *pf;
 
pf = fopen("C:\\users.txt","ab");
 
  if (pf==NULL){
     printf ("ERROR DE LECTURA");
     exit(1);
  }
 
    do{
 
       printf("\nINGRESE NOMBRE DE USUARIO:");
       scanf("%s",&regin.nombre);
 
       printf("\nINGRESE PASSWORD:");
       scanf("%s",&regin.pass);
       
        if(strlen(regin.nombre)>14 || strlen(regin.pass)>5){ //evitamos un overflow
            system("clear");
            printf("Nombre o Password muy largos\n");
            sleep(2);
            system("clear");
         }
           else{
           fprintf(pf,"usuario: %s\npass: %s\n\n",regin.nombre,regin.pass); /*escribimos en el archivo*/
           fclose(pf);  //y lo cerramos
           i++;
           }
           
         

    }while (i==0);
system("clear");
printf("usuario Registrado\n");
}



Saludos...Taul.


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 4 Mayo 2010, 08:46 am
Esa no es la mejor manera de evitar un overflow ya que por mas que lo chequees luego, el overflow sucede igual. En todo caso debería usar fgets para leer las cadenas o especificar la cantidad de caracteres en scanf. De cualquier manera es mejor utilizar fgets ya que la cantidad a leer se indica en los argumentos, lo cual es obviamente una ventaja.

Por otro lado, si utilizas estructuras y abrís el archivo en modo binario, es conveniente trabajarlo de esa forma (fwrite, fread, por ejemplo).

En cuanto al scanf, no debes utilizar el ampersand con cadenas. Seguramente en ese caso no de error, pero si lo daría si la memoria del array es reservada en forma dinámica.

Y como ultimo, las variables globales deben evitarse en la medida de lo posible (Lo cual aplica en el 99.9% de las veces)

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: misterharry en 4 Mayo 2010, 08:46 am
        if(strlen(regin.nombre)>14 || strlen(regin.pass)>5){ //evitamos un overflow
            system("clear");
            printf("Nombre o Password muy largos\n");
            sleep(2);
            system("clear");
         }

disculpa, pero que hace exactamente la funcion strlen()???
y sleep() en que libreria esta??? esta disponible para linux???
hago muchas preguntas??? XD
gracias por todas las ayudas
 ^^


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 4 Mayo 2010, 08:56 am
strlen (http://www.cplusplus.com/reference/clibrary/cstring/strlen/)
sleep (http://www.opengroup.org/onlinepubs/000095399/functions/sleep.html)



Título: Re: Manejo de Archivos duda!
Publicado por: taul en 4 Mayo 2010, 09:03 am
si tenes razon se provoca el overflow igual...bueno che lo escribi al bardo recien.

seria mejor un

scanf("%14s",&regin.nombre);

tomaria solo los 14 primeros char...

con respecto al ab...puedes trabajarlo perfectamente con fprintf...acordate q no lo estamos leyendo simplemente escribimos en el.para poder utilizar fwrite..deberias crear un buffer+añadir todo a un buffer+escribir el buffer en el archivo esto es = a desperdiciar memoria al vicio.

si debes declarar dentro de main tiene razon Littlehorse..aparte te ahorara dolores de cabezas el dia de mañana.

misterharry strlen debuelve un valor int el cual contine la cantidad de caracteres q contiene un buffer....y sleep no me acuerdo pero creo q en stdio.h...si esta disponible para linux al igual que todas las func de la lib standar...en windows en vez de ingresar segundos debes ingresar ms.


saludos.


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 4 Mayo 2010, 09:12 am
Ya se que se puede usar fprintf, pero en el caso de tratar el archivo en modo binario y estar utilizando estructuras, es preferible trabajarlo de esa forma.

Si vos guardas un nombre (15 caracteres, 15 bytes) mas un password (6 caracteres, 6 bytes) es exactamente lo mismo que guardar la estructura entera (21 bytes) con la diferencia que guardando la estructura no estas limitado estrictamente al acceso secuencial del archivo.

PD: sleep no es estándar.

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: taul en 4 Mayo 2010, 09:18 am
PD: sleep no es estándar.

ja siempre crei q era estadar...grax por la info siempre se aprende algo nuevo.


Título: Re: Manejo de Archivos duda!
Publicado por: Mr.Blue en 4 Mayo 2010, 18:47 pm
aca pongo el codigo es uno ya escrito que lo unico que quise es optimizarlo el codigo fue publicado ya pero para no mesclar las dudas cree un tema aparte
es el codigo que puse no puse todo el codigo ya que crei que no era necesario ya que por donde creo q viene el problema talvez sea por el ingreso de datos que es la informacion que quiero guardar.
Código
  1. #include <stdio.h>
  2. #include <conio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5.  
  6. struct datos {
  7. char nombre [15];// nombre del usuario
  8. char pass [6];//password del usuario
  9. char acceso [21];//acceso del usuario
  10. char tipo [2];//tipo de acceso
  11. };
  12. void main()
  13. { int i=1;
  14.  
  15. datos regin;
  16.  
  17. FILE *pf; // apunta al archivo
  18.  
  19.  
  20. pf=fopen ("C:\\users.txt","at+");
  21. // C:\Program Files\Counter-Strike\cstrike\addons\amxmodx\configs
  22. if (pf==NULL)
  23.  {
  24. printf ("ERROR DE LECTURA");
  25. getch();
  26. exit(1);
  27.  }
  28.  
  29.  for(i=1;i<=1;i++) {
  30. printf ("\nINGRESE NOMBRE DE USUARIO:");
  31. gets (regin.nombre);
  32.  
  33. printf ("\nINGRESE PASSWORD DE USUARIO:");
  34. gets (regin.pass);
  35.  
  36. printf ("\nINGRESE ACCESO:");
  37. gets (regin.acceso);
  38. printf ("\nINGRESE TIPO DE ACCESO:");
  39. gets (regin.tipo);
  40.  
  41. fwrite (&regin,sizeof(datos),1,pf);
  42. }
  43. fclose (pf);
  44.  
  45. //re leo grabacion y compruebo
  46. pf=fopen ("C:\\users.txt","r");
  47. if (pf == NULL){
  48. printf ("ERROR DE ACCESO");
  49. getch();
  50. exit(1);
  51. }
  52. fread (&regin,sizeof (datos),1,pf);
  53.  
  54. while (!feof(pf)){
  55. fread (&regin,sizeof (datos),1,pf);
  56. printf("NOMBRE DE USUARIO:%s    PASS:%s ACCESO:%s TIPO DE ACCESO:%s",regin.nombre,regin.pass,regin.acceso,regin.tipo);
  57. fread (&regin,sizeof (datos),1,pf);
  58.  }
  59. fclose (pf);
  60. getch();
  61. }
  62.  



edito: bueno ahi por lo q veo que dice littlehorse  voy a cambiar el gets pro un fgets aver que pasa

strlen: calcula la longitud de la cadena, no incluye el "\0" del final
sleep: si no me equivoco es un tiempo de espera sleep (1000); un segundo aunque la diferencia con delay (1000); no se cual es tube varios problemas una vuelta a programar en tc me andabla el delay pero en borlard o dev ninguna de las dos jaja me tiraba error de compilacion en esas lineas

EI: juntando mensajes.

Sigo con el problema ultimamente viendo, por ahi es un problema en las cadenas
aver como explicarme
en primer lugar vamos ignorar el overflow, por ahora.
bueno tengo q puedo ingresar en nombre 15 caracteres en pass 6 caracteres, ect
ahora esto esta dentro de una estructura para mi el error esta en que si ingreso en nombre 10 caracteres me estan sobrando 5 caracteres talves rellena los suigientes 5 caracteres con basura del buffer osea por lo q tenia entendido al apretar la tecla enter este actua como \0 o \n dependiendo que use

bueno ahora mi pregunta como implemento algo para q coloque el \0 al final de la cadena ingresada
en este momento estoy pensando en un strlen para q me cuente la longitud de la cadena y colocar un \0 al final de la cadena ingresada pero no se como implementarlo i si es de esta manera q deberia hacerlo.


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 7 Mayo 2010, 21:28 pm
A pesar que no deberías usar gets, gets debería finalizar la cadena con un NULL en forma automática. Obviamente los problemas del overflow no se pueden obviar así que te vuelvo a decir que pruebes con fgets.

Por lo pronto sigue habiendo errores en ese codigo, falta un typedef.

En el while, haces esto:

mientras no sea el final
             leo el archivo;
                   imprimo;
             leo el archivo;

Si lo miras bien, cuando se realiza la segunda vuelta del ciclo, hay una lectura que no la imprimes, ya que en vez de imprimir el contenido previamente leido, vuelves a leer.

Usa el buscador y revisa los códigos que ya existen sobre estructuras, y mira también el manejo de fgets. Lo tendrás claro rápidamente y podrás recodificar ese ejercicio.

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: taul en 7 Mayo 2010, 22:40 pm
Littlehorse te repito...no puede usar fgets porque no esta leyendo un archivo.esta leyendo desde el teclado y guardandolo en un buffer.

el code q puse yo esta bien..probalo

cambia esto:

scanf("%14s",&regin.nombre);
scanf("%5s",&regin.pass);

saludos.


Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 7 Mayo 2010, 22:56 pm
Taul, vamos por partes:

Código
  1. scanf("%14s",&regin.nombre);

Primero: El ampersand esta de mas. Creo que ya te he dicho, el identificador del array es un puntero que apunta a la primera posición de dicho arreglo. De la forma que lo haces solo funciona porque el puntero direcciona el mismo lugar que la primera referencia, intenta hacer lo mismo pero reservando memoria dinámica para el arreglo y veras mas claro el error.

Segundo: Si tienes 20 llamadas a scanf, y luego necesitas modificar el tamaño del arreglo, tienes que modificar todas las llamadas a scanf. Con fgets, la cantidad a leer es un argumento que puede ser pasado mediante -por ejemplo- una variable, una constante, una llamada a otra función, o lo que sea que se te ocurra.

Tercero: Precisamente leer de un archivo es leer desde un stream, y el input del teclado es precisamente, un stream.

Código
  1. fgets(buff,size,stdin);

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: leogtz en 7 Mayo 2010, 23:20 pm
No te ofendas, taul, pero, ¿así quieres crear un sistema operativo?


Título: Re: Manejo de Archivos duda!
Publicado por: Mr.Blue en 8 Mayo 2010, 02:03 am
haber haber disculpa Littlehorse que sea un toque duro de entender  :xD,
en primer lugar lo del typedef ? en donde me falta eso? en la estuctura ?

Código
  1. typedef struct datos {
  2. char nombre [15];// nombre del usuario
  3. char pass [6];//password del usuario
  4. char acceso [15];//acceso del usuario
  5. char tipo [2];//tipo de acceso
  6. };

asi? o es otra cosa a lo q te referis?
segundo lugar
intento ingresar con fgets pero no tengo resultado aver si esta mal la sintaxis
Código
  1. fgets (regin.nombre,15, stdin); // o esta
  2. fgets (regin.nombre,15, fp); //pongo las dos porq con ninguna de las dos hay resultado
otra cosa aca tmb que veo es el fgets lee el archivo asociado en la cadena de caracteres s.
osea lee una cadena de caracteres desde el archivo. pero mi cadena esta en la stuctura


PD: lo del overflow digo de que no importa por ahora porq quiero consentrar en lo del ingreso ese y bueno despues agregare lo del overflow pero por el momento la persona que ejecuta el programa sabe que no tiene q probocar un overflow  :laugh:


Otra cosa tmb, el progrmaa en si funciona, osea hace lo q tiene q hacer y guarda los datos ahora bueno que los guarde mal, es por lo q pregunte nuevamente el porque pasa esto, osea no es que no guarde lo q se ingresa por lo contrario se guarda pero junto con basura.

Desde ya gracias por las respuestas y Littlehorse gracias por la paciencia  :P jaja



Título: Re: Manejo de Archivos duda!
Publicado por: Littlehorse en 8 Mayo 2010, 02:30 am
haber haber disculpa Littlehorse que sea un toque duro de entender  :xD,
en primer lugar lo del typedef ? en donde me falta eso? en la estuctura ?

Código
  1. typedef struct datos {
  2. char nombre [15];// nombre del usuario
  3. char pass [6];//password del usuario
  4. char acceso [15];//acceso del usuario
  5. char tipo [2];//tipo de acceso
  6. };

Es que vos en el código declaras la estructura así:

Código
  1. datos regin;

Y eso si no pones un typedef es incorrecto, en todo caso seria:

Código
  1. typedef struct data
  2. {
  3. //lo que sea
  4. }datos;

De no hacer eso, al declarar la estructura tendrías que hacer:

Código
  1. struct data regin;


Citar
intento ingresar con fgets pero no tengo resultado aver si esta mal la sintaxis
Código
  1. fgets (regin.nombre,15, stdin); // o esta
  2. fgets (regin.nombre,15, fp); //pongo las dos porq con ninguna de las dos hay resultado
otra cosa aca tmb que veo es el fgets lee el archivo asociado en la cadena de caracteres s.
osea lee una cadena de caracteres desde el archivo. pero mi cadena esta en la stuctura


A lo que voy con fgets es que la uses para leer desde el teclado, es decir con stdin. Si utilizas fgets con fp (el puntero al archivo) lees una cadena desde el archivo que maneja ese puntero. A lo que me refería, a grandes rasgos, es que uses fgets en reemplazo de gets, no en reemplazo de fread.
También tienes algunas confusiones entre el modo binario y el modo texto en el manejo de archivos, son dos cosas distintas. Se tratan de distinta forma, y se usan distintas funciones. Busca información sobre ello para tener ciertos conceptos un poco mas sólidos.

Citar
Otra cosa tmb, el progrmaa en si funciona, osea hace lo q tiene q hacer y guarda los datos ahora bueno que los guarde mal, es por lo q pregunte nuevamente el porque pasa esto, osea no es que no guarde lo q se ingresa por lo contrario se guarda pero junto con basura.

Revisa lo que te dije del while, la lectura la haces mal, no te enteras cuando llegas al final del archivo y te salteas una lectura a la hora de imprimir (es decir, lees dos veces, imprimes una).

Citar
Desde ya gracias por las respuestas y Littlehorse gracias por la paciencia  :P jaja

De nada, para eso estamos!

Saludos!


Título: Re: Manejo de Archivos duda!
Publicado por: Mr.Blue en 10 Mayo 2010, 18:55 pm
Buenisimo gracias por la ayuda, ya me estoy a modificar los errores no pude el finde pero ahora tengo tiempo jaja

 ;-)


Título: Re: Manejo de Archivos duda!
Publicado por: taul en 13 Mayo 2010, 04:54 am
no me ofendo para nada Leo Gutiérrez...yo programo de una forma y a lo mejor vos de otra..si esta bien programado o no eso pasa por cada uno..creo q podemos opinar diferente o no? para eso estamos juntados aca en el foro..porque todos vemos las cosas desde un punto de vista diferente...quien decide cual es la mejor opinion? pues el q formulo la pregunta...yo no vine al foro a criticar los conocimientos de nadie..solo opino al igual q cualquier usuario. si vos Leo Gutiérrez pensas q no se programar...respeto tu opinion..nadie se puede ofender por la opinion de alguin no?


Saludos...Taul.


Título: Re: Manejo de Archivos duda!
Publicado por: leogtz en 13 Mayo 2010, 05:03 am
No pienso que no sabes programar.