| Ver tema anterior :: Ver siguiente tema |
| Autor | Mensaje |
|---|
cigoba

Registrado: 27 Ago 2007 Mensajes: 30
| Publicado: 26/09/2007 7:46 pm | | | Título: Juzgen este codigo C |
| Hola gente
Coloco este codigo en C que hice con el Dev-C++ para que ustedes me digan que es lo que tengo que agrear, cambiar y/o quitar para que el programa funcione de la mejor manera posible. El programa crea un archivo de texto llamado SALIDA.txt en el cual puedo ingresar datos.
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int c; FILE *pf; char *s="C:\\SALIDA.txt"; if((pf=fopen(s, "w")) == NULL) { puts("\n\nERROR DE APERTURA DEL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } while((c=getchar()) != EOF) fputc(c, pf); if(fclose(pf) != 0) /* Hago esta validacion por si hay error al cerrar el programa */ { puts("\n\n ERROR AL CERRAR EL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } puts("\n\n"); system("PAUSE"); return EXIT_SUCCESS; }
|
Otra duda que tengo con respecto a este programa es el siguiente: Cuano lo ejecuto e ingreso por consola los datos:
El Lenguaje de Programacion C
y justo despues de la letra 'C' pulso <Ctrl>+<C> y el programa finaliza (se cierra). El problema es que cuando abro el archivo desde C:\SALIDA.txt y veo su contendio, aparece:
El Lenguaje de Programacion
es decir, me quitó la última línea (la letra 'C'). Como hago para que cuando pulse <Ctrl>+<C> justo despues de la ultima linea me quede guardada en el archivo tambien esta linea y no me la elimine?. Para que me guarde todas las lineas tengo que pulsar un <Enter> despues de la ultima linea y recien pulsar <Ctrl>+<C>, pero no quiero hacer esto.
El valor que toma EOF (fin de archivo) es el valor generado por <Ctrl>+<C>? Hice este programa para imprimir el valor de EOF, corriganme si esta bien. El valor que obtengo es -1.
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int c=EOF; char p; p= (char) c; printf("%d", p); putchar('\n'); system("PAUSE"); return EXIT_SUCCESS; }
|
Gracias de antemano  _________________ esta es mi firma. |
|
| Volver arriba | |
 |
mamntc02
Registrado: 30 Abr 2007 Mensajes: 226
| Publicado: 27/09/2007 12:11 am | | | Título: |
| Hola,
el código me parece bastante correcto, aunque si quieres ser puritano: - No es necesario poner void en la definición de main, de hecho el estandard define dos maneras distintas de definir main():| Código: | int main(){...} //ó int main(int argc, char** argv){...} | Los hay q son super-puritanos y dicen q es una abominación usar el void (sobretodo en C++), pero tampoco hay q ser tan estricto, aunque quién lo diga sea el propio creador de C++ (Bjarne Stroustrup). Lo comentan aquí, donde también te dan un link para ver el documento original de Bjarne donde comenta lo de la 'abominación'.... Este rollo sólo te lo comento por pura curiosidad  - Inicializa siempre tus variables, por tanto:| Código: | int c = 0; FILE *fp = NULL; |
- Ya q el nombre del archivo es constante ponlo:| Código: | const char* s = "c:\\salida.txt"; | Esto no hace cambiar nada, ya q un literal es siempre constante, pero le da más énfasis.
Respecto a lo q comentar de q no se te guarda 'C' es normal. <Ctrl+C> lanza un 'interrupt signal', la cual hace abortar el programa, y como el contenido del buffer (la letra 'C') no ha sido procesada no la graba. Para q sea procesada debe ser leída por getchar y esto se produce al pulsa <enter>. <Ctrl+C> no genera EOF, si no recuerdo mal (pero no estoy al 100% seguro) sería <Ctrl+Z> quien generaría el EOF. No obstante quizá en tu caso (y ya q no lees de archivo) deberías poner otro control q no sea EOF. Si tampoco recuerdo mal, también es cierto q EOF está definido como -1 o también puede q lo encuentres definido como 0xFF ó 0xFFFF (si es wchar). Esto lo puedes mirar en tu fichero <stdio.h>
Saludos. |
|
| Volver arriba | |
 |
rir3760

Registrado: 01 Oct 2004 Mensajes: 3588 Ubicación: Mexico
| Publicado: 27/09/2007 6:37 am | | | Título: |
| Como ya te respondio mamntc02 la falta de datos completos en el archivo se debe a que estas terminando el programa mediante {CONTROL} + 'C'. En MS DOS y MS Windows para generar la señal de fin de archivo o EOF debes utilizar la combinacion {CONTROL} + 'Z'.
En cuanto al uso de "int main(void)" vs "int main()" en C se pueden dar argumentos de peso sobre cual de estas preferir:
A) En el caso de "int main(void)" esta es una de las dos formas que se mencionan en el estandar de C.
B) En el caso de "int main()" esta es una definicion y el mismo estandar aclara que la definicion de una funcion utilizando un par de parentesis vacios indica que esa funcion no recibe argumentos.
Supongo que esto (el uso de (void) en main) proviene del hecho que una declaracion como esta:
En C se toma como una funcion que recibe un numero no determinado de argumentos, si se desea indicar mediante un prototipo que la funcion no recibe argumentos no hay otra opcion mas que utilizar void:
En el caso de la macro EOF esta se define en <stdio.h> y segun el estandar de C debe ser un valor negativo de tipo "int".
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
|
| Volver arriba | |
 |
|
cigoba

Registrado: 27 Ago 2007 Mensajes: 30
| Publicado: 27/09/2007 7:02 am | | | Título: |
| Es realmente importante inicializar siempre a 0 o NULL mis varibles de esta forma:?
| Código: | int c = 0; FILE *fp = NULL;
|
Ahora hago una modificación de mi código anterior. Les parece que es necesario utilizar la funcion perror como sigue? Y otra cosa, si no se produce un error de cierre de fichero, debo colocar un else para cerrar dicho fichero?
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int c; /* Es importante hacerlo int c = 0; ? */ FILE *pf; /* Es importante hacerlo FILE *fp = NULL; ? */ const char *s="C:\\SALIDA.txt"; if((pf=fopen(s, "w")) == NULL) { perror("SALIDA.txt"); puts("\n\nERROR DE APERTURA DEL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } while((c=getchar()) != EOF) fputc(c, pf); if(fclose(pf) != 0) { perror("SALIDA.txt"); puts("\n\n ERROR AL CERRAR EL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } else fclose(pf); puts("\n\n"); system("PAUSE"); return EXIT_SUCCESS; }
|
_________________ esta es mi firma. |
|
| Volver arriba | |
 |
digies

Registrado: 18 Nov 2005 Mensajes: 176 Ubicación: Cono Sur
| Publicado: 27/09/2007 6:16 pm | | | Título: |
| Hola
Es preferible la declaración: int main(void) que int main() porque la primera es más explícita para el compilador.
En tu caso no es necesario inicializar las variables int c=0; e FILE *fp=NULL;
| Cita: | Les parece que es necesario utilizar la funcion perror como sigue?
|
No es necesario pero sí convenietne porque perror da más información del porqué no se abre el archivo.
| Cita: | Y otra cosa, si no se produce un error de cierre de fichero, debo colocar un else para cerrar dicho fichero?
|
No, porque si no se produce un error devuelve 0 y se cierra el fichero. También puede ser:
| Código: | if(!fclose(pf)) /* Error al cerrar el archivo */
|
o así
| Código: | if(fclose(pf) == EOF) /* Error al cerrar el archivo */
|
porque la función fclose retorna cero si el stream fue cerrado con éxito. Si se detectaron errores, entonces retorna EOF.
Macro EOF en Ansi C: #define EOF
#define EOF (-1) DJGPP #define EOF (-1) Borland #define EOF (-1) Dev-C++
Un saludo |
|
| Volver arriba | |
 |
cheroky
Registrado: 22 Sep 2005 Mensajes: 1331 Ubicación: En ecx esperando un call
| Publicado: 27/09/2007 6:45 pm | | | Título: |
| Inicializar los punteros a NULL (dicho sea de paso unica direccion explicita invalida valida para un puntero) se considera buena practica, al menos en el codigo (digamos) mas formal.
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
|
| Volver arriba | |
 |
|
rir3760

Registrado: 01 Oct 2004 Mensajes: 3588 Ubicación: Mexico
| Publicado: 27/09/2007 9:34 pm | | | Título: |
| En este caso concreto (el primer programa de cigoba) es innecesario inicializar las variables ya que el primer uso de estas es en operaciones de asignacion.
En las operaciones de lectura y/o escritura en archivos es recomendable verificar si la salida del bucle es causada por error, por ejemplo:
| Código: | while ((c = getchar()) != EOF) if (fputc(c, pf) == EOF) break; if (ferror(pf)){ /* manejo de error */ }
/* ... */ |
Aunque habra que imponerse (mediante el sentido comun) ciertos limites, por ejemplo si ocurren errores tanto en la salida estandar (stdout) como en la salida estandar de errores (stderr) no hay mucho que uno pueda hacer (salvo la terminacion del programa).
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
|
| Volver arriba | |
 |
cigoba

Registrado: 27 Ago 2007 Mensajes: 30
| Publicado: 28/09/2007 6:20 pm | | | Título: |
| Valorando cada una de sus respuestas (mamntc02, rir3760, digies, y cheroky), aqui coloco mi codigo final:
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int c; FILE *pf= NULL; /* Lo inicializo a NULL para que el codigo quede mas elegante */ const char *s="C:\\SALIDA.txt"; if((pf=fopen(s, "w")) == NULL) { perror("SALIDA.txt"); puts("\n\nERROR DE APERTURA DEL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } while((c=getchar()) != EOF) if(fputc(c, pf) == EOF) break; if(ferror(pf)) { puts("\n\nHubo un ERROR\n\n"); system("PAUSE"); exit(EXIT_FAILURE); } if(fclose(pf) == EOF) { perror("SALIDA.txt"); puts("\n\n ERROR AL CERRAR EL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } puts("\n\n"); system("PAUSE"); return EXIT_SUCCESS; }
|
Gracias  _________________ esta es mi firma. |
|
| Volver arriba | |
 |
cheroky
Registrado: 22 Sep 2005 Mensajes: 1331 Ubicación: En ecx esperando un call
| Publicado: 29/09/2007 4:08 am | | | Título: |
| Quizás el bucle de captura quieras hacerlo del siguiente modo.
| Código: | do{ if((c = fgetc(stdin)) == EOF) break; fputc(c, pf); fflush(pf); }while(c != EOF); |
Entre otras cosas evitas que al morir el proceso inesperadamente o quedarse zombi pierdas todos los datos menos la ultima linea.
S2. _________________ - Explícito es mejor que implícito. - Simple es mejor que complejo. - Complejo es mejor que complicado. - Plano es mejor que anidado. - Ralo es mejor que denso. |
|
| Volver arriba | |
 |
|
cigoba

Registrado: 27 Ago 2007 Mensajes: 30
| Publicado: 29/09/2007 2:02 pm | | | Título: |
| Gracias cheroky, lo implemetaré. _________________ esta es mi firma. |
|
| Volver arriba | |
 |
digies

Registrado: 18 Nov 2005 Mensajes: 176 Ubicación: Cono Sur
| Publicado: 29/09/2007 2:50 pm | | | Título: |
| A tu último código también puedes agregarle fflush(stderr) así:
| Código: | #include <stdio.h> #include <stdlib.h>
int main(void) { int c; FILE *pf= NULL; const char *s="C:\\SALIDA.txt"; if((pf=fopen(s, "w")) == NULL) { perror("SALIDA.txt"); fflush(stderr); puts("\n\nERROR DE APERTURA DEL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } while((c=getchar()) != EOF) if(fputc(c, pf) == EOF) break; if(ferror(pf)) { puts("\n\nHubo un ERROR\n\n"); fflush(stderr); system("PAUSE"); exit(EXIT_FAILURE); } if(fclose(pf) == EOF) { perror("SALIDA.txt"); fflush(stderr); puts("\n\n ERROR AL CERRAR EL ARCHIVO\n\n"); system("PAUSE"); return EXIT_FAILURE; } puts("\n\n"); system("PAUSE"); return EXIT_SUCCESS; }
|
Un saludo |
|
| Volver arriba | |
 |
|
|