Duda con un programa que hice - Do while y creacion de ficheros/archivos

Iniciado por Fabi0lo, 1 Mayo 2012, 20:35 PM

0 Miembros y 1 Visitante están viendo este tema.

Fabi0lo

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.

[youtube=425,350]http://www.youtube.com/watch?v=tNqxK6a6Law&feature=plcp[/youtube]

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.

#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.



exel

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:


#include <stdio.h>

void vaciar_buffer();

int main()
{
   FILE *archivo;

   char nombretxt[256], mensaje[256];
   int opc;

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

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

        scanf("%d", &opc);

        switch (opc)
        {

            case 1:

               printf("\nIngrese el nombre del archivo que desea crear o al que desea añadirle un mensaje: ");
               
               vaciar_stdin();
               fgets(nombretxt, sizeof(nombretxt), stdin)

               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: ");
               
               vaciar_stdin();
               fgets(mensaje, sizeof(mensaje), stdin)

               fputs(mensaje, archivo);

               fclose(archivo);

               break;

           case 2:

               printf("\nIngrese el nombre del archivo que desea crear o sobrescribir: ");
               
               vaciar_stdin();                
               fgets(nombretxt, sizeof(nombretxt), stdin)

               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: ");
               
               vaciar_stdin();                
               fgets(mensaje, sizeof(mensaje), stdin)

               fputs(mensaje, archivo);

               fclose(archivo);

               break;

           case 3:

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

           default:

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

        vaciar_stdin();
        printf("\n");

   } while (opc != 3);

   return 0;
}




void vaciar_stdin(){

    while (getc(stdin) != EOF)
       ;

}



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