Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Fabi0lo en 1 Mayo 2012, 20:35 pm



Título: Duda con un programa que hice - Do while y creacion de ficheros/archivos
Publicado por: Fabi0lo en 1 Mayo 2012, 20:35 pm
Hola a todos!, miren, me sumo a este subforo de c por que un programa no me funciona como quiero, lo que intente hacer es algo parecido a lo que hizo este tipo en este video.

tNqxK6a6Law

Un menu para escoger el nombre del archivo a crear, si se desea sobrescribir o añadir un mensaje, el mensaje que poner y otra opcion para salir del programa.

El problema que ya me rompe la cabeza hace media hora es que, si uso scanf("%s"), no puedo guardar el mensaje con espacios, si uso gets() o fgets() apartir de la 2º vuelta del do while me genera mucho problema, como que se salta los gets() o fgets() y no me deja ingresar otros nombres de archivos, etc..., al igual que si uso scanf("%[^\n]"), entonces les pido su ayuda, no entiendo muy bien por que sucede el problema, quiero poder poner mensaje con espacios en blanco en mi archivo de texto, pero tambien quiero poder elegir las opciones que puse todas las vueltas que quiera, ¿algun experto en la materia que me ayude?.

Mi codigo esta aqui.

Código:
#include <stdio.h>

int main()
{
    FILE *archivo;

    char nombretxt[256], mensaje[256];
    int es_primera = 0;
    int opc;

    do
     {
         if (es_primera)
         printf("\n");

         printf("Ingrese una opcion...\n");

         printf("\n1. Crear o anadir al archivo");
         printf("\n2. Crear o sobreescribir archivo");
         printf("\n3. Salir\n\n");

         scanf("%i", &opc);

         switch (opc)
         {

             case 1:

                printf("\nIngrese el nombre del archivo que desea crear o al que desea añadirle un mensaje: ");
                scanf("%s", nombretxt);

                archivo = fopen(nombretxt, "a");

                if (archivo != NULL)
                printf("\nArchivo creado con exito");
                    else
                    printf("\nAh ocurrido un error en la creacion del archivo");

                printf("\n\nIngrese el mensaje que dese grabar en el archivo de texto: ");
                scanf("%s", mensaje);

                fputs(mensaje, archivo);

                fclose(archivo);

                break;

            case 2:

                printf("\nIngrese el nombre del archivo que desea crear o sobrescribir: ");
                scanf(" %s", nombretxt);

                archivo = fopen(nombretxt, "w");

                if (archivo != NULL)
                printf("\nArchivo creado con exito");
                    else
                    printf("\nAh ocurrido un error en la creacion del archivo");

                printf("\n\nIngrese el mensaje que dese grabar en el archivo de texto: ");
                scanf(" %s", mensaje);

                fputs(mensaje, archivo);

                fclose(archivo);

                break;

            case 3:

                printf("\nSaliendo del programa...");
                break;

            default:

                printf("\nNo es una opcion valida");
                break;
         }

    es_primera++;

    } while (opc != 3);

    return 0;
}

Se los agradeceria demasiado.

Saludos.




Título: Re: Duda con un programa que hice - Do while y creacion de ficheros/archivos
Publicado por: exel en 1 Mayo 2012, 22:52 pm
Hola

 El problema que planteas es ya un clasico entre los aprendices de C. La situacion es que como dijiste, scanf() con %s solo lee una cadena hasta el espacio, mientras que por otro lado fgets() o gets() leen la cadena hasta el salto de linea ('\n'). Pero la pregunta es: ¿donde se almacena esta cadena antes de ser transferida por scanf(),gets() o fgets()?; pues la respuesta es un buffer llamado stdin el cual sigue almacenando caracteres no leidos por las funciones mensionadas. Por lo tanto es necesario vaciar este buffer antes de ser utilizado otra vez por estas funciones o cualquier otra que intente leer de stdin.

 No lo he probado, pero creo que esta bien la modificacion que he realizado de tu codigo:

Código
  1. #include <stdio.h>
  2.  
  3. void vaciar_buffer();
  4.  
  5. int main()
  6. {
  7.    FILE *archivo;
  8.  
  9.    char nombretxt[256], mensaje[256];
  10.    int opc;
  11.  
  12.    do
  13.     {
  14.         printf("Ingrese una opcion...\n");
  15.  
  16.         printf("\n1. Crear o anadir al archivo");
  17.         printf("\n2. Crear o sobreescribir archivo");
  18.         printf("\n3. Salir\n\n");
  19.  
  20.         scanf("%d", &opc);
  21.  
  22.         switch (opc)
  23.         {
  24.  
  25.             case 1:
  26.  
  27.                printf("\nIngrese el nombre del archivo que desea crear o al que desea añadirle un mensaje: ");
  28.  
  29.                vaciar_stdin();
  30.                fgets(nombretxt, sizeof(nombretxt), stdin)
  31.  
  32.                archivo = fopen(nombretxt, "a");
  33.  
  34.                if (archivo != NULL)
  35.                    printf("\nArchivo creado con exito");
  36.                else
  37.                    printf("\nAh ocurrido un error en la creacion del archivo");
  38.  
  39.                printf("\n\nIngrese el mensaje que dese grabar en el archivo de texto: ");
  40.  
  41.                vaciar_stdin();
  42.                fgets(mensaje, sizeof(mensaje), stdin)
  43.  
  44.                fputs(mensaje, archivo);
  45.  
  46.                fclose(archivo);
  47.  
  48.                break;
  49.  
  50.            case 2:
  51.  
  52.                printf("\nIngrese el nombre del archivo que desea crear o sobrescribir: ");
  53.  
  54.                vaciar_stdin();                
  55.                fgets(nombretxt, sizeof(nombretxt), stdin)
  56.  
  57.                archivo = fopen(nombretxt, "w");
  58.  
  59.                if (archivo != NULL)
  60.                    printf("\nArchivo creado con exito");
  61.                else
  62.                    printf("\nAh ocurrido un error en la creacion del archivo");
  63.  
  64.                printf("\n\nIngrese el mensaje que dese grabar en el archivo de texto: ");
  65.  
  66.                vaciar_stdin();                
  67.                fgets(mensaje, sizeof(mensaje), stdin)
  68.  
  69.                fputs(mensaje, archivo);
  70.  
  71.                fclose(archivo);
  72.  
  73.                break;
  74.  
  75.            case 3:
  76.  
  77.                printf("\nSaliendo del programa...");
  78.                break;
  79.  
  80.            default:
  81.  
  82.                printf("\nNo es una opcion valida");
  83.                break;
  84.         }
  85.  
  86.         vaciar_stdin();
  87.         printf("\n");
  88.  
  89.    } while (opc != 3);
  90.  
  91.    return 0;
  92. }
  93.  
  94.  
  95.  
  96.  
  97. void vaciar_stdin(){
  98.  
  99.    while (getc(stdin) != EOF)
  100.        ;
  101.  
  102. }
  103.  
  104.  

Podrias utilizar la funcion fflush(stdin) para limpiar el buffer de entrada(stdin), sin embargo a mi me gusta este procedimiento de resolucion.

Como stdin es considerado como un fichero, EOF es lo que devuelve getc() en caso de que el buffer stdin este vacio.

Saludos