elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Estamos en la red social de Mastodon


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)  (Leído 2,839 veces)
El-Brujito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« en: 23 Junio 2016, 01:54 am »

Hola, que tal, soy un hombre de 26 años, la primera ves que yo entre a esta pagina web fue hace mas de 7 años, yo me habia registrado para entonces con otro nick, y bueno esta pagina me trae muchos recuerdos, pero vamos al punto.

Sucede que estoy intentando crear un programa en el lenguaje de programación C, pero necesito ayuda, ya que el programa tiene un problema, y es que durante el tiempo de ejecucion, luego de la compilacion, presenta un error.

Es un programa que crea un archivo de registros, y tambien lo lee e imprime su contenido en pantalla.

El problema esta al momento de imprimir en pantalla los registros creados en el archivo, ya que si usted crea el archivo con 5 registros, el programa va a imprimir 6 registros, es decir, siempre imprime un registro mas que no fue solicitado, y esto no es correcto, porque yo quiero que imprima el contenido del archivo, y no registros "fantasmas".

Asi que necesito a algun experto que me ayude.

Este es el codigo en cuestion


Un programa con dos funciones, CreateFile: crea un archivo con la cantidad de registros ingresada por el usuario; y ReadFile: lee un archivo e imprime en pantalla los registros que contiene ese archivo, parece ser que en esta funcion (ReadFile) es donde esta el problema pero no puedo comprender o encontrar el error

Código
  1. // testing file structure and visibility
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4.  
  5. void CreateFile();
  6. void ReadFile();
  7.  
  8. struct Record
  9. {
  10. char Charac[20];
  11. };
  12.  
  13. int main()
  14. {
  15. int Command=-1,i=0;
  16. struct Record DefaultRecord;
  17.  
  18. for(i=0;i<=19;i++)
  19. {
  20.  
  21. if(i==19)
  22. {
  23. DefaultRecord.Charac[i]='@';
  24. }
  25. else
  26. {
  27. DefaultRecord.Charac[i]='#';
  28. }
  29.  
  30. }
  31.  
  32. while(Command!=0)
  33. {
  34.  
  35. printf("Main menu:\n");
  36. printf("\n1 - Create a new file.\n");
  37. printf("2 - read a file.\n");
  38. printf("0 - end program.\n");
  39. scanf("%d",&Command);
  40.  
  41. switch(Command)
  42. {
  43. case 1:
  44. CreateFile();
  45. break;
  46. case 2:
  47. ReadFile();
  48. break;
  49. default:
  50. printf("%d is not a valid command.\n",Command);
  51. }
  52.  
  53. }
  54.  
  55. return 0;
  56. }
  57.  
  58. void CreateFile()
  59. {
  60. int nR=0,i=0,n=0,x=0;
  61. char FileName[20]; // FIX
  62. FILE *fPtr;
  63. struct Record XRecord;
  64.  
  65. for(i=0;i<=19;i++)
  66. {
  67.  
  68. if(i==19)
  69. {
  70. XRecord.Charac[i]='@';
  71. }
  72. else
  73. {
  74. XRecord.Charac[i]='#';
  75. }
  76.  
  77. }
  78.  
  79. printf("\nPlease enter the number of records to create the file: ");
  80. scanf("%d",&nR);
  81. printf("\nPlease enter the name of the file including his type (aaa.aa): ");
  82. scanf("%s",&FileName);
  83.  
  84. if((fPtr=fopen(FileName,"w"))==NULL)
  85. {
  86. printf("nFile %s could not be opened.\n",FileName);
  87. }
  88. else
  89. {
  90. for(i=1;i<=nR;i++)
  91. {
  92.    for(x=0;x<=19;x++)
  93.    {
  94.    fprintf(fPtr,"%c",XRecord.Charac[x]);
  95.    }
  96. n++;
  97. printf("n=%d\n",n);
  98. }
  99. fclose(fPtr);
  100. }
  101. }
  102.  
  103. void ReadFile()
  104. {
  105. int v=0,i=0,n=0,x=0;
  106. FILE *fPtr;
  107. char FileName[20];
  108. struct Record XRecord;
  109.  
  110. for(i=0;i<=19;i++)
  111. {
  112. if(i==19)
  113. {
  114. XRecord.Charac[i]='Y';
  115. }
  116. else
  117. {
  118. XRecord.Charac[i]='x';
  119. }
  120. }
  121. printf("\nPlease enter FileName: ");
  122. scanf("%s",&FileName);
  123.  
  124. if((fPtr=fopen(FileName,"r"))==NULL)
  125. {
  126. printf("%s could not be opened.\n",FileName);
  127. }
  128. else
  129. {
  130. printf("\n");
  131.  
  132. while(!feof(fPtr))
  133. {
  134.    n++;
  135.  
  136.    for(x=0;x<=19;x++)
  137.    {
  138.    fscanf(fPtr,"%c",&XRecord.Charac[x]);
  139.    }
  140. printf("Record Number:%d\n",n);
  141.  
  142. for(i=0;i<=19;i++)
  143. {
  144. printf("%c",XRecord.Charac[i]);
  145. }
  146. printf("\n");
  147. }
  148.  
  149. }
  150. fclose(fPtr);
  151. }
  152.  

Alguien ayudeme por favor  :-(


« Última modificación: 23 Junio 2016, 02:04 am por El-Brujito » En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #1 en: 23 Junio 2016, 02:26 am »

Hola después de entender mas o menos tu codigo y encontrar algunos detalles no veo bien cual sea el problema.

Si solo si escribes el archivo cuantos bytes pesa?

Detalles vistos:

En la funcion readfile el ciclo de inicialización sale sobrando.

Código
  1. for(i=0;i<=19;i++)
  2. {
  3. if(i==19)
  4. {
  5. XRecord.Charac[i]='Y';
  6. }
  7. else
  8. {
  9. XRecord.Charac[i]='x';
  10. }
  11. }

Por que no usar fwrite para escribir toda la estrucuctura de golpe?

Ejemplos:



Saludos


En línea

El-Brujito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #2 en: 23 Junio 2016, 03:00 am »

Citar
Hola después de entender mas o menos tu codigo y encontrar algunos detalles no veo bien cual sea el problema.

Hola amigo, gracias por responder, dios te bendiga, el problema esta en que la funcion ReadFile imprime en pantalla un registro adicional el cual no fue solicitado, por ejemplo si usted crea un archivo con 2 registros, ReadFile mostrara en pantalla 3 registros, de los cuales el tercero no tengo idea de donde habra salido; si usted crea el archivo con 3 registros, ReadFile mostrara 4,
Citar
hay un error porque si el archivo es creado con X numero de registros, esa cantidad es la que debe de mostrar, pero ReadFile esta mostrando X+1 registros

Citar
Si solo si escribes el archivo cuantos bytes pesa?

Pesa 20 bytes, segun windows, (quizas el tamaño varie segun el computador)

Detalles vistos:
Citar
En la funcion readfile el ciclo de inicialización sale sobrando.

¿Sobrando mi amigo querido?, usted dice que se desborda el buffer? de verdad que no entiendo porque si el array tiene 20 elementos, esta inicialización, la cual es solo para rellenar, en realidad sus valores no se usan, pues, no le veo nada de malo

Código
  1. for(i=0;i<=19;i++)
  2. {
  3. if(i==19)
  4. {
  5. XRecord.Charac[i]='Y';
  6. }
  7. else
  8. {
  9. XRecord.Charac[i]='x';
  10. }
  11. }

Citar
Por que no usar fwrite para escribir toda la estrucuctura de golpe?
Primero estaba probando con fwrite y fread, pero como el programa continuo presentando el error, intente con fprintf y fscanf, para ver si se arreglaba, pero no se arreglo.

Citar
Ejemplos:



Saludos

Gracias por ese ejemplo AlbertoBSD, lo tomare en cuenta
En línea

AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #3 en: 23 Junio 2016, 03:12 am »

Hola

Citar
¿Sobrando mi amigo querido?, usted dice que se desborda el buffer? de verdad que no entiendo porque si el array tiene 20 elementos, esta inicialización, la cual es solo para rellenar, en realidad sus valores no se usan, pues, no le veo nada de malo

me refiero a que : ¿Para que inicializar el buffer con datos? si al final vas a terminar sobreescribiendo sobre el con los datos desde el archivo.

Intenta escribir el archivo con este ciclo:

Código
  1. for(i=0;i<nR;i++)
  2. {
  3.    for(x=0;x<20;x++)
  4.    {
  5.    fprintf(fPtr,"%c",XRecord.Charac[x]);
  6.    }
  7. n++;
  8. printf("n=%d\n",n);
  9. }

Personalmente no me gusta usar <= en los codigos, prefiero usar simplemente mejor que.

Saludos
En línea

class_OpenGL


Desconectado Desconectado

Mensajes: 437

Si usas Direct3D, no eres mi amigo :P


Ver Perfil
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #4 en: 23 Junio 2016, 03:40 am »

He compilado el código y me ha dado unas cuantas advertencias. Deberías vigilarlas. Yo no voy a mostrar las advertencias pues lo puedes mirar tu mismo, pero aun así es preferible que un programa no las tenga, pues son potenciales errores que después cuesta solucionar (lo digo por experiencia).

Respecto al error, es bastante fastidiante (me ha pasado hace poco xD). Lo que pasa es que el indicador de feof se activa solo cuando se intenta leer un carácter pero ya no quedan más. Entonces, cuando terminas de leer el último registro, no llegas a activar el feof y por lo tanto el while se ejecuta una vez más.

Para solucionarlo, puedes comprobar que no has llegado al final del archivo antes de mostrar el supuesto registro:

Código
  1. while(!feof(fPtr)) {
  2. n++;
  3.  
  4. for(x = 0; x <= 19; x++)
  5. fscanf(fPtr, "%c", &XRecord.Charac[x]);
  6.  
  7. if(!feof(fPtr)) { // Compruébalo aquí
  8. printf("Record Number:%d\n",n);
  9.  
  10. for(i=0;i<=19;i++)
  11. printf("%c", XRecord.Charac[i]);
  12.  
  13. printf("\n");
  14. }
  15. }
En línea

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL
AlbertoBSD
Programador y
Moderador Global
***
Desconectado Desconectado

Mensajes: 3.696


🏴 Libertad!!!!!


Ver Perfil WWW
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #5 en: 23 Junio 2016, 06:58 am »

Si es cierto!!!!

Una solucion alterna a este problema es determinar la longitud del archivo y dividirlo entre el tamaño la estructura y asi solo leer el numero exacto de datos.

Posiblemente te pasaba lo mismo con el fread.

Saludos
En línea

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #6 en: 23 Junio 2016, 16:12 pm »

Eso es porqué al leer el tercer registro todavía no has llegado al final del archivo por eso el bucle itera una última vez.

Crea una variable tipo char (yo la llamo c) y cambia las líneas 132 y 133 por las siguientes:
Código:
while((c = fgetc(fPtr)) != EOF) {
    ungetc(c, fPtr);
En línea

El-Brujito

Desconectado Desconectado

Mensajes: 3


Ver Perfil
Re: Ayuda - Programa en C que muestra algo que no debe mostrar (FILE,fprintf,fscanf)
« Respuesta #7 en: 23 Junio 2016, 16:43 pm »

Gracias a los que respondieron, anotare sus nombres por alli para agredecerles cuando pueda, he resuelto el problema utilizando este codigo, sin embargo sus respuestas (AlbertoBSD, class_OpenGL, MAFUS), son muy utiles, ya que tambien resuelven el problema mediante codigos similares

Este es el que he usado, sustituyendo el while por este:

Código
  1. while(1)
  2. {
  3.    n++;
  4.  
  5.    for(x=0;x<=19;x++)
  6.    {
  7.    fscanf(fPtr,"%c",&XRecord.Charac[x]);
  8.    }
  9.    if(feof(fPtr))
  10.    {
  11.        break;
  12.    }
  13. printf("Record Number:%d\n",n);
  14.  
  15. for(i=0;i<=19;i++)
  16. {
  17. printf("%c",XRecord.Charac[i]);
  18. }
  19. printf("\n");
  20. }

He compilado el código y me ha dado unas cuantas advertencias. Deberías vigilarlas. Yo no voy a mostrar las advertencias pues lo puedes mirar tu mismo, pero aun así es preferible que un programa no las tenga, pues son potenciales errores que después cuesta solucionar (lo digo por experiencia).

Respecto al error, es bastante fastidiante (me ha pasado hace poco xD). Lo que pasa es que el indicador de feof se activa solo cuando se intenta leer un carácter pero ya no quedan más. Entonces, cuando terminas de leer el último registro, no llegas a activar el feof y por lo tanto el while se ejecuta una vez más.

Para solucionarlo, puedes comprobar que no has llegado al final del archivo antes de mostrar el supuesto registro:

Código
  1. while(!feof(fPtr)) {
  2. n++;
  3.  
  4. for(x = 0; x <= 19; x++)
  5. fscanf(fPtr, "%c", &XRecord.Charac[x]);
  6.  
  7. if(!feof(fPtr)) { // Compruébalo aquí
  8. printf("Record Number:%d\n",n);
  9.  
  10. for(i=0;i<=19;i++)
  11. printf("%c", XRecord.Charac[i]);
  12.  
  13. printf("\n");
  14. }
  15. }

Excelente respuesta mi amigo!

Si es cierto!!!!

Una solucion alterna a este problema es determinar la longitud del archivo y dividirlo entre el tamaño la estructura y asi solo leer el numero exacto de datos.

Posiblemente te pasaba lo mismo con el fread.

Saludos

Tu respuesta es muy util


Eso es porqué al leer el tercer registro todavía no has llegado al final del archivo por eso el bucle itera una última vez.

Crea una variable tipo char (yo la llamo c) y cambia las líneas 132 y 133 por las siguientes:
Código:
while((c = fgetc(fPtr)) != EOF) {
    ungetc(c, fPtr);

Teneis toda la razon, tu respuesta es muy buena, y explica claramente como resolver el problema.

Os aprecio a todos por la ayuda que me han dado
« Última modificación: 23 Junio 2016, 16:46 pm por El-Brujito » En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines