fgets and variants

Discussion in 'C Programming' started by Diego, Apr 2, 2004.

  1. Diego

    Diego Guest

    Hi,

    Using gcc 2.96

    This message was suggested by a thread started by Knak on 21/03/04

    The question is:

    When I run the following code, if I want to introduce a second pile of
    data, the fgets is ignored. I've been even tempted to use gets. Please,
    compile and try.

    I've tested fgets, and a simulation of fgets suggested in the cited
    thread. It's quite frustrating to seeall my efforts working one time and
    failing when calling fgets a second time from the samefunction.

    Please look at the following piece of code. First is a small
    program (just the beginning of an exercise, not veryfing any user input),
    and then following a variation picked up from the above
    cited thread. (Thanks to Minti, isingh AT acm DOT org).

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>

    typedef struct buque /* El nombre buque no sirve aqu de nada, solo como recordatorio */
    {
    char nombre[41];
    float desplazamiento; /* Toneladas */
    float carga; /* Capacidad de carga, toneladas */
    float eslora; /* metros */
    unsigned short int tripulantes; /* Nmero de tripulantes */
    } buque; /* Asigna el tipo struct a buque mediante el typedef */

    void alta (buque * flota) /* Si no declaramos un puntero al struct, no pasa los datos
    durante la ejecucin de la funcin*/
    {
    char nbarco[41];

    printf ("\n*************ALTA DE BUQUES****************\n\n");

    printf ("\nNombre del buque?:\t");
    fgets(nbarco, 41, stdin); /* aade newline al final */
    //fgets(nbarco, strlen(nbarco), stdin); /* quita un carcter al final */
    strcpy( flota->nombre, nbarco );

    printf ("\nDesplazamiento en Tm?:\t");
    scanf ("%f", &flota->desplazamiento);

    printf ("\nCapacidad de carga en Tm?:\t");
    scanf ("%f", &flota->carga);

    printf ("\nEslora en mts?:\t");
    scanf ("%f", &flota->eslora);

    printf ("\nNmero de tripulantes.?:\t");
    scanf ("%d", &flota->tripulantes);

    }

    void grabaFichero (FILE *fp, char* formato, buque flota)
    {
    formato = "\n\
    Nombre del buque: \t%-40s\n\
    Desplazamiento: \t%6.2f Tm\n\
    Carga: \t\t%6.2f Tm\n\
    Eslora: \t\t%4.2f mts\n\
    Tripulacin: \t%4d\n\n";

    fprintf (fp,
    formato,
    flota.nombre,
    flota.desplazamiento,
    flota.carga,
    flota.eslora,
    flota.tripulantes
    );
    }

    void imprime (char * formato, buque flota)
    {
    formato = "\n\
    Nombre del buque: \t%-40s\n\
    Desplazamiento: \t%6.2f Tm\n\
    Carga: \t\t%6.2f Tm\n\
    Eslora: \t\t%4.2f mts\n\
    Tripulacin: \t%4d\n\n";

    printf ( formato,
    flota.nombre,
    flota.desplazamiento,
    flota.carga,
    flota.eslora,
    flota.tripulantes
    );
    }

    int main()
    {
    buque barco;
    char * datos;
    char correcto = 'n';
    char respuesta = 's';

    FILE *fichero;
    while (NULL == (fichero = fopen("naviera.txt", "a+"))) /* si naviera.txt existe, lo abre
    y si no lo crea*/
    {
    printf ("\nError al abrir el fichero de buques\n");
    return -1;
    }

    while (tolower(respuesta) != 'n')
    {
    while (tolower(correcto) != 's')
    {
    alta (&barco);
    imprime (datos, barco);
    printf ("\nSon correctos los datos del buque (S o N)?: ");
    scanf("%s", &correcto);
    }

    grabaFichero(fichero, datos, barco);
    printf ("\nDar de alta ms buques (S o N)?: ");
    scanf("%s", &respuesta);
    }

    fclose(fichero);

    return 0;
    }

    _______________________

    Following the variation tested, getting the same result:
    (replaces the 1st paragraph following ***Alta....., and of course I've included
    the #define VERDAD 1)


    int tamano = 1;
    char* nbarco = ( char * ) malloc( tamano );
    int i = 0;
    int c;
    while ( VERDAD ) {
    c = getchar();
    if ( c == '\n' || c == EOF ) { nbarco = '\0' ; break; }
    else {
    if ( i == tamano ) {
    nbarco = ( char * ) realloc ( nbarco, tamano *= 2 );
    if ( ! nbarco ) {
    exit ( EXIT_FAILURE );
    }
    }
    nbarco[i++] = c;
    }
    }

    Thanks very much for your help,
    Diego
    damulco AT telefonica DOT net
    Diego, Apr 2, 2004
    #1
    1. Advertising

  2. in comp.lang.c i read:

    >When I run the following code, if I want to introduce a second pile of
    >data, the fgets is ignored.


    actually it's your lack of understanding of how scanf works and too little
    debugging (skill?) that is causing you to think that the second fgets is
    being ignored. scanf examines each byte on the input stream, as soon as it
    reaches one that no longer is acceptable for the type of conversion being
    performed it puts it back onto the stream and finalizes the conversion.
    you are probably pressing enter (i.e., '\n') after each of the values. the
    %d's have no use for '\n' so it is left on the input stream, and since %d
    skips leading whitespace it's not a problem for scanf, but when all your
    %d's are done then whatever stopped the last conversion (probably a '\n')
    is left on the stream. the second fgets terminates copying as soon as it
    copies a '\n' (or one less than the limit), which is likely the first thing.

    > char nbarco[41];


    > fgets(nbarco, 41, stdin); /* aade newline al final */
    > //fgets(nbarco, strlen(nbarco), stdin); /* quita un carcter al final */


    since nbarco is an automatic variable without an initializer and not
    otherwise assigned prior to this point you cannot use strlen() safely.
    further i'm not sure why you would want to read at most as many characters
    as the string already happens to contain. the first is the correct usage
    of fgets, though i'd probably use sizeof nbarco instead of the `magic'
    value 41 -- it's too easy for them to get out of sync otherwise.

    --
    a signature
    those who know me have no need of my name, Apr 3, 2004
    #2
    1. Advertising

  3. On Sat, 03 Apr 2004 00:15:22 +0200, Diego <>
    wrote:

    >Hi,
    >
    >Using gcc 2.96
    >
    >This message was suggested by a thread started by Knak on 21/03/04
    >
    >The question is:
    >
    >When I run the following code, if I want to introduce a second pile of
    >data, the fgets is ignored. I've been even tempted to use gets. Please,
    >compile and try.
    >
    >I've tested fgets, and a simulation of fgets suggested in the cited
    >thread. It's quite frustrating to seeall my efforts working one time and
    >failing when calling fgets a second time from the samefunction.
    >
    >Please look at the following piece of code. First is a small
    >program (just the beginning of an exercise, not veryfing any user input),
    >and then following a variation picked up from the above
    >cited thread. (Thanks to Minti, isingh AT acm DOT org).


    If you are going to use scanf and fgets together, you must make sure
    that after calling scanf you remove the '\n' that is left in the
    stream. Otherwise, the next time you call fgets it reads that
    character and believes it is all done.



    <<Remove the del for email>>
    Barry Schwarz, Apr 3, 2004
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. John Harrison
    Replies:
    7
    Views:
    1,186
    Thomas Lorenz
    Nov 12, 2004
  2. Replies:
    2
    Views:
    315
    Tony Nelson
    Nov 24, 2005
  3. DanielJohnson

    C compiler variants

    DanielJohnson, Feb 20, 2007, in forum: C Programming
    Replies:
    1
    Views:
    352
    Richard Heathfield
    Feb 20, 2007
  4. Adem
    Replies:
    10
    Views:
    590
    Old Wolf
    Nov 12, 2008
  5. Adem
    Replies:
    10
    Views:
    474
    Old Wolf
    Nov 12, 2008
Loading...

Share This Page