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

 

 


Tema destacado: Introducción a Git (Primera Parte)


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Plantilla para trabajar con archivos en lenguaje C.
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Plantilla para trabajar con archivos en lenguaje C.  (Leído 5,218 veces)
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Plantilla para trabajar con archivos en lenguaje C.
« en: 11 Abril 2017, 18:41 pm »

Hola, gente ¿cómo están?
Lo que me trae en este caso no es para pedir ayuda porque el programa no funciona, lo que quisiera es que me digan que debería cambiar, que les parece, ¿está bien encarado?, estoy consiente que esto se lo debería preguntar a un profe o a un amigo, pero como ya algunos conocen por mi edad (65) no tengo ni una cosa ni la otra,-
Es todo, espero que alguien con mucho tiempo lo revice, no tengo ningún apuro. -   

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX 80
  6.  
  7. void copiaDeSeguridad( FILE *ptrGuiaTel, FILE *ptrGtTemp ); //GT0001
  8. void ingresarFrase( char frase[] ); //GT0002
  9. void copiar( FILE *ptrGuiaTel, FILE *ptrGtTemp, char frase[] ); //GT0003
  10. void errorEscritura( FILE *ptrGuiaTel, FILE *ptrGtTemp ); //GT0004
  11. void mensaje( void );
  12.  
  13.  
  14. int main( int argc,char **argv ){
  15. FILE *ptrGuiaTel = NULL, *ptrGtTemp = NULL;
  16. char frase[MAX];
  17.  
  18. copiaDeSeguridad( ptrGuiaTel, ptrGtTemp ); //GT0001
  19. ingresarFrase( frase ); //GT0002
  20. copiar( ptrGuiaTel, ptrGtTemp, frase ); //GT0003
  21.  
  22. return EXIT_SUCCESS;
  23. }
  24.  
  25.  
  26. void copiaDeSeguridad( FILE *ptrGuiaTel, FILE *ptrGtTemp ){ //GT0001
  27. char c, x;
  28.  
  29. if( !( ptrGuiaTel = fopen( "archGuiaTel.txt", "r" ))){
  30. mensaje();
  31. exit(1);
  32. }
  33. if( !( ptrGtTemp = fopen( "archGtTemp.txt", "w" ))){
  34. mensaje();
  35. exit(1);
  36. }
  37.  
  38. c = fgetc( ptrGuiaTel );
  39. while ( c != EOF ){
  40. x = fputc( c, ptrGtTemp );
  41. if (x != c){
  42. mensaje();
  43. exit(1);
  44. }
  45. c = fgetc( ptrGuiaTel );
  46. }
  47.  
  48. if( ( fclose( ptrGuiaTel ) ) ){
  49. mensaje();
  50. exit(1);
  51. }
  52. if( ( fclose( ptrGtTemp ) ) ){
  53. mensaje();
  54. exit(1);
  55. }
  56. }
  57.  
  58. void ingresarFrase( char frase[] ){ //GT0002
  59. int ok=0;
  60.  
  61. do{
  62. printf( "\n Ingrese frase.....:" );
  63. fgets( frase, MAX, stdin );
  64. ok = strlen( frase );
  65. }while( ok <= 1 );
  66. }
  67.  
  68. void copiar( FILE *ptrGuiaTel, FILE *ptrGtTemp, char frase[] ){ //GT0003
  69.  
  70. if( !(ptrGuiaTel = fopen( "archGuiaTel.txt", "a" ))){
  71. mensaje();
  72. exit(1);
  73. }
  74.  
  75. fprintf( ptrGuiaTel, "%s", frase );
  76.  
  77. if( fflush( ptrGuiaTel ) != 0){
  78. mensaje();
  79. fclose( ptrGuiaTel );
  80. errorEscritura( ptrGuiaTel, ptrGtTemp ); //GT0004
  81. exit(1);
  82. }
  83.  
  84. if( ( fclose( ptrGuiaTel ) ) ){
  85. mensaje();
  86. exit(1);
  87. }
  88. }
  89.  
  90. void errorEscritura( FILE *ptrGuiaTel, FILE *ptrGtTemp ){ //GT0004
  91.  
  92. if( rename("archGtTemp.txt","archGuiaTel.txt") !=0 ){
  93. mensaje();
  94. exit(1);
  95. }
  96.  
  97. if(remove( "archGuiaTel.txt") !=0 ){
  98. mensaje();
  99. exit(1);
  100. }
  101. }
  102.  
  103. void mensaje( void ){
  104. int ch, a;
  105.  
  106. printf( "\n Ha ocurrido un error y el programa finaliza sin cambios en el archivo." );
  107. printf( "\n Pulse una tecla para continuar..."); a = getchar();
  108. if( a != '\n') while ((ch = getchar()) != EOF && ch != '\n');
  109. }
  110.  
  111. /*
  112. GT0001 - Funcion copiaDeSeguridad
  113. Efectuo una copia del archivo original por si fallara la escritura en el mismo, si esto
  114. ocurriera renombro la copia con el mismo nombre que el archivo original y a este lo borro,
  115. con esto me aseguro que el archivo en disco no quede corrupto. -
  116. Si fallara la apertura de los archivos archGuiaTel.txt o archGtTemp.txt imprimo un mensaje
  117. y cierro el programa (mensaje y exit(1)), lo mismo ocurrira si falla la escritura en el archivo temporal (if (x != c){).-
  118. Si la apertura de los 2 archivos es correcta como asi la escritura, solo queda constatar si
  119. el cierre de los mismos ocurre sin errores, de lo contrario se procedera de la misma manera que en la apertura de los mismos (mensaje y exit (1). -
  120. Nota: En esta funcion se abre y se cierra el archivo "archGtTemp.txt".
  121. //GT0002 - Funcion ingresarFrase  
  122. El do-while es para que no se pueda salir de la funcion si no se ha ingresado por lo menos
  123. un dígito.-
  124. //GT0003 - Funcion copiar
  125. Con fprintf( ptrGuiaTel, "%s", frase ); copio la frase en el buffer intermedio y con fflush
  126. copio la frase desde el buffer al disco rigido(archGuiaTel.txt).-
  127. Verifico si la apertura y cierre del archivo ocurre sin errores.-
  128. En el caso de que fallara fflush llamo a la (//GT0004) funcion errorEscritura para renombrar el archivo archGtTemp.txt por archGuiaTel.txt para luego borrar el
  129.                 archivo original que seguramente si no se pudo escribir es porque está corrupto(al final con remove lo borro). -
  130. */

Saludos.


En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #1 en: 11 Abril 2017, 19:58 pm »

No lo he probado pero estilísticamente está mal.

Usas los argumentos de las funciones como una forma de declarar variables locales. Los argumentos solo deberían usarse para que las funciones se comunicasen datos entre llamadas.

Cuando usas argumentos el compilador genera espacio en la pila para alojar dicho dato y después copia el dato que se va a pasar en esa nueva localidad.

He visto que llevas usando esta técnica desde hace tiempo, pero deberías cambiarla lo más pronto posible: declarar variables locales dentro del cuerpo de las funciones y usar los argumentos únicamente para pasar datos.


En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #2 en: 12 Abril 2017, 02:29 am »

Hola.
No logro que me caiga la ficha del todo con lo que propones, te pediría tan solo unos minutos para que me hagas una pequeña función diciéndome lo que hago mal y como seria la forma correcta de hacerlo. -

Gracias MAFUS.
Un gran saludo.
En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #3 en: 15 Abril 2017, 23:57 pm »

Así es tu código corregido:

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX 80
  6.  
  7. void copiaDeSeguridad( void );
  8. void ingresarFrase( char frase[] );
  9. void copiar( char frase[] );
  10. void errorEscritura( void );
  11. void mensaje( void );
  12.  
  13. int main( void ){
  14. char frase[MAX];
  15.  
  16. copiaDeSeguridad( );
  17. ingresarFrase( frase );
  18. copiar( frase );
  19.  
  20. return EXIT_SUCCESS;
  21. }
  22.  
  23.  
  24. void copiaDeSeguridad( void ){
  25.    FILE *ptrGuiaTel;
  26.    FILE *ptrGtTemp;
  27. char c, x;
  28.  
  29. if( !( ptrGuiaTel = fopen( "archGuiaTel.txt", "r" ))){
  30. mensaje();
  31. exit(1);
  32. }
  33. if( !( ptrGtTemp = fopen( "archGtTemp.txt", "w" ))){
  34. mensaje();
  35. exit(1);
  36. }
  37.  
  38. c = fgetc( ptrGuiaTel );
  39. while ( c != EOF ){
  40. x = fputc( c, ptrGtTemp );
  41. if (x != c){
  42. mensaje();
  43. exit(1);
  44. }
  45. c = fgetc( ptrGuiaTel );
  46. }
  47.  
  48. if( ( fclose( ptrGuiaTel ) ) ){
  49. mensaje();
  50. exit(1);
  51. }
  52. if( ( fclose( ptrGtTemp ) ) ){
  53. mensaje();
  54. exit(1);
  55. }
  56. }
  57.  
  58. void ingresarFrase( char frase[] ){
  59. int ok=0;
  60.  
  61. do{
  62. printf( "\n Ingrese frase.....:" );
  63. fgets( frase, MAX, stdin );
  64. ok = strlen( frase );
  65. }while( ok <= 1 );
  66. }
  67.  
  68. void copiar( char frase[] ){
  69.    FILE *ptrGuiaTel;
  70.  
  71. if( !(ptrGuiaTel = fopen( "archGuiaTel.txt", "a" ))){
  72. mensaje();
  73. exit(1);
  74. }
  75.  
  76. fprintf( ptrGuiaTel, "%s", frase );
  77.  
  78. if( fflush( ptrGuiaTel ) != 0){
  79. mensaje();
  80. fclose( ptrGuiaTel );
  81. errorEscritura( );
  82. exit(1);
  83. }
  84.  
  85. if( ( fclose( ptrGuiaTel ) ) ){
  86. mensaje();
  87. exit(1);
  88. }
  89. }
  90.  
  91. void errorEscritura( void ){
  92.  
  93. if( rename("archGtTemp.txt","archGuiaTel.txt") !=0 ){
  94. mensaje();
  95. exit(1);
  96. }
  97.  
  98. if(remove( "archGuiaTel.txt") !=0 ){
  99. mensaje();
  100. exit(1);
  101. }
  102. }
  103.  
  104. void mensaje( void ){
  105. int ch, a;
  106.  
  107. printf( "\n Ha ocurrido un error y el programa finaliza sin cambios en el archivo." );
  108. printf( "\n Pulse una tecla para continuar..."); a = getchar();
  109. if( a != '\n') while ((ch = getchar()) != EOF && ch != '\n');
  110. }
En línea

NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #4 en: 26 Abril 2017, 03:30 am »

Hola, ¿cómo están?
Gracias MAFUS por el código y gracias por el consejo, estaba cometiendo un error de primer grado, lo voy a tener muy en cuenta de aquí en más. --
La ayudita que les pido ahora es la siguiente, alguien me podría decir como hacer para que falle fflush,
(línea 43) para saber el comportamiento total del programa necesito que esto ocurra, intente abrir el archivo archGuiaTel.txt (línea 36) para lectura pero no me ocasiona un error, simplemente no escribe la frase, pero el programa termina normalmente. -   
Es todo y espero puedan darme la respuesta. -

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define MAX 80
  6.  
  7. void ingresarFrase( char frase[] );
  8. void copiar( char frase[] );
  9. void errorEscritura( void );
  10. void copiaDeSeguridad( const char *GtTxt, const char *GtBak );
  11. void mensaje( void );
  12.  
  13. int main( void ){
  14. char frase[MAX];
  15.  
  16. ingresarFrase( frase );
  17. copiar( frase );
  18. copiaDeSeguridad( "archGuiaTel.txt","archGuiaTel.bak" );
  19.  
  20. return EXIT_SUCCESS;
  21. }
  22.  
  23. void ingresarFrase( char frase[] ){
  24. int ok=0;
  25.  
  26. do{
  27. printf( "\n Ingrese frase.....:" );
  28. fgets( frase, MAX, stdin );
  29. ok = strlen( frase );
  30. }while( ok <= 1 );
  31. }
  32.  
  33. void copiar( char frase[] ){
  34. FILE *ptrGtTxt;
  35.  
  36. if( !(ptrGtTxt = fopen( "archGuiaTel.txt", "a" ))){
  37. mensaje();
  38. exit(1);
  39.    }
  40.  
  41. fprintf( ptrGtTxt, "%s", frase );
  42.  
  43. if( fflush( ptrGtTxt ) != 0){
  44. mensaje();
  45. fclose( ptrGtTxt );
  46. errorEscritura( );
  47. exit(1);
  48. }
  49.  
  50. if( ( fclose( ptrGtTxt ) ) ){
  51. mensaje();
  52. exit(1);
  53. }
  54. }
  55.  
  56. void errorEscritura( void ){
  57. if(remove( "archGuiaTel.txt" ) !=0 ){
  58. mensaje();
  59. exit(1);
  60. }
  61.  
  62. if( rename( "archGuiaTel.bak","archGuiaTel.txt") !=0 ){
  63. mensaje();
  64. exit(1);
  65. }
  66. }
  67.  
  68. void copiaDeSeguridad( const char *GtTxt, const char *GtBak ){
  69. FILE *ptrGtTxt, *ptrGtBak;  
  70. char c, x;
  71.  
  72. if( !( ptrGtTxt = fopen( GtTxt, "a" ))){
  73. mensaje();
  74. exit(1);                                
  75. }
  76. if( !( ptrGtBak = fopen( GtBak, "w" ))){
  77. mensaje();
  78. exit(1);                                
  79. }
  80.  
  81. c = fgetc( ptrGtTxt );
  82. while ( c != EOF ){
  83. x = fputc( c, ptrGtBak );
  84. if (x != c){
  85. mensaje();
  86. exit(1);                                
  87. }
  88. c = fgetc( ptrGtTxt );
  89. }
  90.  
  91. if( ( fclose( ptrGtTxt ) ) ){
  92. mensaje();
  93. exit(1);                                
  94. }
  95. if( ( fclose( ptrGtBak ) ) ){
  96. mensaje();
  97. exit(1);                                
  98. }
  99. }
  100.  
  101. void mensaje( void ){
  102. int ch, a;
  103.  
  104. printf( "\n Ha ocurrido un error y el programa finaliza sin cambios en el archivo." );
  105. printf( "\n Pulse una tecla para continuar..."); a = getchar();
  106.    if( a != '\n') while ((ch = getchar()) != EOF && ch != '\n');
  107. }

saludos.
 
En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
kuhi

Desconectado Desconectado

Mensajes: 37


50 shadows of Kappa


Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #5 en: 28 Abril 2017, 01:47 am »

Hola 😊👍🏻, tengo una duda: cuando usáis por ejemplo: void mensaje ( void )
Entiendo que estáis declarando una función tipo void pero no entiendo porqué ponéis void como parámetro... puede ser que estéis definiendo una función sin valor de retorno?
Me podéis explicar por favor??
Muchas gracias ❤️


Enviado desde mi iPhone utilizando Tapatalk
En línea

El conocimiento no ocupa lugar, somos libres de saber cuánto queramos...
MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #6 en: 28 Abril 2017, 10:09 am »

Eso quiere decir que la función no acepta argumentos y no devuelve ningún dato. Es lo mismo que void mensaje(). Es una cuestión de estilos.
En línea

kuhi

Desconectado Desconectado

Mensajes: 37


50 shadows of Kappa


Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #7 en: 28 Abril 2017, 22:14 pm »

Eso quiere decir que la función no acepta argumentos y no devuelve ningún dato. Es lo mismo que void mensaje(). Es una cuestión de estilos.
Es más correcto utilizarlo así o es 100% idéntico? Saludos y gracias 😊👍🏻


Enviado desde mi iPhone utilizando Tapatalk
En línea

El conocimiento no ocupa lugar, somos libres de saber cuánto queramos...
NOB2014


Desconectado Desconectado

Mensajes: 366



Ver Perfil
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #8 en: 28 Abril 2017, 22:44 pm »

Hola.
Pongo void en las funciones que no reciben parametros porque una vez leí que era una ayuda para el compilador pero por más que busco de donde lo saque, no lo encuentro, desde ese momento, en todas mis prácticas lo hago de esa manera. -
Aprovecho para decirles que encontré la manera para forzar a fflush que de error. -

Saludos.
En línea

abraza las cosas y personas malas como si fueran tu mas preciada joya,Son tus mas grandes maestros de paciencia sabiduría y amor y cuando lo abrazas dejan de causar dolor.-
CalgaryCorpus


Desconectado Desconectado

Mensajes: 323


Ver Perfil WWW
Re: Plantilla para trabajar con archivos en lenguaje C.
« Respuesta #9 en: 29 Abril 2017, 17:43 pm »

Un poco de historia.
Los primeros compiladores de C eran bastante rudimentarios y no hacian chequeos, suponiendo que el programador sabia lo que hacia. En particular los parametros de las funciones. Al inicio, el lenguaje C permitia no especificar parametros como en
Código:
int mifuncion()
y luego mas adelante invocar esa funcion asi:

Código:
valor = mifuncion( a, b, c );

y el compilador no reclamaba nada.

Con el tiempo, el lenguaje se estandarizo y le agregaron el que uno pueda especificar los tipos de los parametros, pero aun manteniendo la compatibilidad hacia atras, vale decir, si no especificabas nada, no habia chequeos, pero si especificabas algo, entonces habia chequeos.

En este caso, si ponias
Código:
int mifuncion(void)

entonces el compilador va a reclamar si invocas la funcion con algun parametro, pues al poner el void ahi, le estas pidiendo explicitamente al compilador que chequee, y este no va a permitir la invocacion con mas parametros.

Ahora ya no importa la compatibilidad hacia atras, si no pones parametros en la definicion de la funcion el compilador va a chequear que NO pases ningun parametro, del mismo modo si pones void entre los parentesis.

Resumen
  • mucho antes: no habia chequeo alguno
  • luego: chequeo si especificas void
  • ahora: chequeo siempre
En línea

Aqui mi perfil en LinkedIn, invitame un cafe aqui
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Trabajar cn archivos
Programación Visual Basic
Lambda 1 1,481 Último mensaje 18 Abril 2006, 22:28 pm
por NYlOn
Trabajar con archivos xml en java!!!!
Java
01munrra 5 4,708 Último mensaje 23 Enero 2012, 00:37 am
por Littlehorse
cual es la mejor clase de java para trabajar con archivos
Java
jhonatanAsm 9 6,639 Último mensaje 17 Mayo 2012, 04:10 am
por RyogiShiki
Mejor clase para trabajar con archivos C++
Programación C/C++
Kaxperday 7 4,080 Último mensaje 14 Agosto 2015, 16:26 pm
por Kaxperday
Qué lenguaje me conviene para trabajar con datos de un sitio web?
Programación General
The Swash 6 4,870 Último mensaje 14 Abril 2016, 18:16 pm
por [u]nsigned
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines