_cgets() Problem

Hey,

I have a (to me) strange problem with the _cgets() function. I have a simple word guessing game. The user can take a shot at guessing the word. The first time I call _cgets() everything works fine. Only the second time when I call it, it skips the statement and returns a zero string to my array. Why doesn't it work the second time? The third time it works again... the fourth time it doesn't. Do i need to clean up my string buffer in any way?

I'll post part of the code:
[code]
//Variable declaration (at the beginning of the sub)
char guess[15] = { 12 }; //First byte contains max string len
char* pGuess;
...
//Later on I use this code to get input from the user
_cputs( "
Guess the word: " );
guess[0] = wordLen; //Set max lenght of the guessed word
pGuess = _cgets( guess );
[/code]
Like I said, the first time this works... the second it skips it (The values of guess: guess[0] = wordLen; guess[1] = 0; guess[2] = 0; guess[3] = 10)

Thanks in advance (I'm still a bit of a noob when it comes to these things)
Richard
«1

Comments

  • : Hey,
    :
    : I have a (to me) strange problem with the _cgets() function. I have a simple word guessing game. The user can take a shot at guessing the word. The first time I call _cgets() everything works fine. Only the second time when I call it, it skips the statement and returns a zero string to my array. Why doesn't it work the second time? The third time it works again... the fourth time it doesn't. Do i need to clean up my string buffer in any way?
    :
    : I'll post part of the code:
    : [code]
    : //Variable declaration (at the beginning of the sub)
    : char guess[15] = { 12 }; //First byte contains max string len
    : char* pGuess;
    : ...
    : //Later on I use this code to get input from the user
    : _cputs( "
    Guess the word: " );
    : guess[0] = wordLen; //Set max lenght of the guessed word
    : pGuess = _cgets( guess );
    : [/code]
    : Like I said, the first time this works... the second it skips it (The values of guess: guess[0] = wordLen; guess[1] = 0; guess[2] = 0; guess[3] = 10)
    :
    : Thanks in advance (I'm still a bit of a noob when it comes to these things)
    : Richard
    :

    [green]
    I had the same problem with fgets() but I figured out that I needed to flush the stdin since it was still retaining junk. Try [red]fflush(stdin);[/red] and see if that will fix your problem.
    [/green]

  • [b][red]This message was edited by BitByBit_Thor at 2005-7-13 9:59:27[/red][/b][hr]
    [b][red]This message was edited by BitByBit_Thor at 2005-7-13 9:58:26[/red][/b][hr]
    : : Hey,
    : :
    : : I have a (to me) strange problem with the _cgets() function. I have a simple word guessing game. The user can take a shot at guessing the word. The first time I call _cgets() everything works fine. Only the second time when I call it, it skips the statement and returns a zero string to my array. Why doesn't it work the second time? The third time it works again... the fourth time it doesn't. Do i need to clean up my string buffer in any way?
    : :
    : : I'll post part of the code:
    : : [code]
    : : //Variable declaration (at the beginning of the sub)
    : : char guess[15] = { 12 }; //First byte contains max string len
    : : char* pGuess;
    : : ...
    : : //Later on I use this code to get input from the user
    : : _cputs( "
    Guess the word: " );
    : : guess[0] = wordLen; //Set max lenght of the guessed word
    : : pGuess = _cgets( guess );
    : : [/code]
    : : Like I said, the first time this works... the second it skips it (The values of guess: guess[0] = wordLen; guess[1] = 0; guess[2] = 0; guess[3] = 10)
    : :
    : : Thanks in advance (I'm still a bit of a noob when it comes to these things)
    : : Richard
    : :
    :
    : [green]
    : I had the same problem with fgets() but I figured out that I needed to flush the stdin since it was still retaining junk. Try [red]fflush(stdin);[/red] and see if that will fix your problem.
    : [/green]
    :
    :

    I tried to flush the input before using
    [code]
    while (_kbbit() != 0) _getch();
    [/code]

    That didn't seem to work (it was almost as if the CrLf ("
    ") sequence was still in the buffer and could not be 'flushed' by the code above).

    I figured then that fflush(stdin) would work, but even that does not :-S

    Should I try to 'clean' my buffer up, eg. fill guess[] with 0?

    Greets...
    Richard





  • : [b][red]This message was edited by BitByBit_Thor at 2005-7-13 9:59:27[/red][/b][hr]
    : [b][red]This message was edited by BitByBit_Thor at 2005-7-13 9:58:26[/red][/b][hr]
    : : : Hey,
    : : :
    : : : I have a (to me) strange problem with the _cgets() function. I have a simple word guessing game. The user can take a shot at guessing the word. The first time I call _cgets() everything works fine. Only the second time when I call it, it skips the statement and returns a zero string to my array. Why doesn't it work the second time? The third time it works again... the fourth time it doesn't. Do i need to clean up my string buffer in any way?
    : : :
    : : : I'll post part of the code:
    : : : [code]
    : : : //Variable declaration (at the beginning of the sub)
    : : : char guess[15] = { 12 }; //First byte contains max string len
    : : : char* pGuess;
    : : : ...
    : : : //Later on I use this code to get input from the user
    : : : _cputs( "
    Guess the word: " );
    : : : guess[0] = wordLen; //Set max lenght of the guessed word
    : : : pGuess = _cgets( guess );
    : : : [/code]
    : : : Like I said, the first time this works... the second it skips it (The values of guess: guess[0] = wordLen; guess[1] = 0; guess[2] = 0; guess[3] = 10)
    : : :
    : : : Thanks in advance (I'm still a bit of a noob when it comes to these things)
    : : : Richard
    : : :
    : :
    : : [green]
    : : I had the same problem with fgets() but I figured out that I needed to flush the stdin since it was still retaining junk. Try [red]fflush(stdin);[/red] and see if that will fix your problem.
    : : [/green]
    : :
    : :
    :
    : I tried to flush the input before using
    : [code]
    : while (_kbbit() != 0) _getch();
    : [/code]
    :
    : That didn't seem to work (it was almost as if the CrLf ("
    ") sequence was still in the buffer and could not be 'flushed' by the code above).
    :
    : I figured then that fflush(stdin) would work, but even that does not :-S
    :
    : Should I try to 'clean' my buffer up, eg. fill guess[] with 0?
    :
    : Greets...
    : Richard
    :
    [green]
    Have you tried putting fflush(stdin) after each _cgets()? Thats where you should put it. Your guess array is not the problem since the junk like carriage return is still in the stdin buffer from the previous call to function _cgets(). Also wouldn't it be better to use fgets() anyways? Using fgets you can forgo the buffer length in your array since you specify it in the 2nd parameter.
    [/green]

    [code]
    _cgets(guess);
    fflush(stdin);

    or using fgets()

    fgets(guess, sizeof(guess), stdin);
    fflush(stdin);
    [/code]
  • : [green]
    : Have you tried putting fflush(stdin) after each _cgets()? Thats where you should put it. Your guess array is not the problem since the junk like carriage return is still in the stdin buffer from the previous call to function _cgets(). Also wouldn't it be better to use fgets() anyways? Using fgets you can forgo the buffer length in your array since you specify it in the 2nd parameter.
    : [/green]
    :
    : [code]
    : _cgets(guess);
    : fflush(stdin);
    :
    : or using fgets()
    :
    : fgets(guess, sizeof(guess), stdin);
    : fflush(stdin);
    : [/code]
    :

    Actually... I tried it before and after the _cgets() call, just to be sure.

    I messed around with it a bit and it seems that my buffer always needs to be large enough to hold the string lenght, plus the "
    " characters...
    I'll try to explain: the word is 5 letters long. So then I would set the max string to 7 so the "
    " sequence can be read also. However, this fails ofcourse if the user decides to input a 6 letter word :-S
    And for some reason, neither my flush code, nor the fflush(stdin) seem to have any effect...

    Greets...
    Richard

  • : : [green]
    : : Have you tried putting fflush(stdin) after each _cgets()? Thats where you should put it. Your guess array is not the problem since the junk like carriage return is still in the stdin buffer from the previous call to function _cgets(). Also wouldn't it be better to use fgets() anyways? Using fgets you can forgo the buffer length in your array since you specify it in the 2nd parameter.
    : : [/green]
    : :
    : : [code]
    : : _cgets(guess);
    : : fflush(stdin);
    : :
    : : or using fgets()
    : :
    : : fgets(guess, sizeof(guess), stdin);
    : : fflush(stdin);
    : : [/code]
    : :
    :
    : Actually... I tried it before and after the _cgets() call, just to be sure.
    :
    : I messed around with it a bit and it seems that my buffer always needs to be large enough to hold the string lenght, plus the "
    " characters...
    : I'll try to explain: the word is 5 letters long. So then I would set the max string to 7 so the "
    " sequence can be read also. However, this fails ofcourse if the user decides to input a 6 letter word :-S
    : And for some reason, neither my flush code, nor the fflush(stdin) seem to have any effect...
    :
    : Greets...
    : Richard
    :
    [green]
    According to MSDN if you had a 5 letter string then the size of the array would have to be at least 8. guess[0] would be the max size of the array. guess[1] would be the actual size after crlf and the last element would be ''.
    [/green]


  • : :
    : [green]
    : According to MSDN if you had a 5 letter string then the size of the array would have to be at least 8. guess[0] would be the max size of the array. guess[1] would be the actual size after crlf and the last element would be ''.
    : [/green]
    :
    :
    :

    Where did you read that? c-style character arrays do not contain the length of the string nor the number of bytes allocated to it. using fgets() the length of the string would have to be at least 7 (5 characters, plush '
    ' and ').
    [code]
    char guess[7];
    fgets(guess,sizeof(guess),stdin);
    [/code]

    So if I typed in "Hello" , guess could contain this:
    [code]
    guess[0] = 'H'
    guess[1] = 'e'
    guess[2] = 'l'
    guess[3] = 'l'
    guess[4] = 'o'
    guess[5] = '
    '
    guess[6] = 0
    [/code]

    using fflush(stdin) normally has undefined behavior -- that is to say the C standards do not define what happens when you attempt to flush stdin. It may work the way you want with some compilers but may not work at all (or trash your ocmputer) with others.
  • [b][red]This message was edited by shaolin007 at 2005-7-14 11:45:33[/red][/b][hr]
    [red] Where did you read that?[/red]

    [green]http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_CRT__cgets.asp[/green]

    : using fflush(stdin) normally has undefined behavior -- that is to say the C standards do not define what happens when you attempt to flush stdin. It may work the way you want with some compilers but may not work at all (or trash your ocmputer) with others.
    :
    [green]
    I guess that probably is true since I was using the file msvcrt.dll. I figured when I was having the problem with fgets(,,stdin) in my program it was corrected using fflush(stdin). I figured that it cleared the junk out of the stdin buffer which is defined by _iob[0]structure.
    [/green]


    [red]edit[/red]

    [green]
    I looked up fflush() on MSDN and it recommends flushing the (stdin) before using a stdin function because the previous stdin function might of overran the buffer. fflush() will clear the contents of this buffer.

    example code from MSDN
    [code]
    Example
    // crt_fflush.c
    #include
    #include

    int main( void )
    {
    int integer;
    char string[81];

    /* Read each word as a string. */
    printf( "Enter a sentence of four words with scanf: " );
    for( integer = 0; integer < 4; integer++ )
    {
    scanf( "%s", string );
    // Security caution!
    // Beware allowing user to enter data directly into a buffer
    // without checking for buffer overrun possiblity.
    printf( "%s
    ", string );
    }

    /* You must flush the input buffer before using gets. */
    fflush( stdin ); // fflush on input stream is an extension to the C standard
    printf( "Enter the same sentence with gets: " );
    gets( string );
    printf( "%s
    ", string );
    }
    [/code]
    [/green]


  • [b][red]This message was edited by stober at 2005-7-14 11:54:8[/red][/b][hr]
    : [green]
    : I looked up fflush() on MSDN and it recommends flushing the (stdin) before using a stdin function because the previous stdin function might of overran the buffer. fflush() will clear the contents of this buffer.[/green]
    :

    Microsoft does not set the ANSI standards. Yes, their compiler allows fflush(stdin), but most others do not. And Microsoft compilers are notorious for not being ANSI compliant in many other areas too.


  • : [b][red]This message was edited by stober at 2005-7-14 11:54:8[/red][/b][hr]
    : : [green]
    : : I looked up fflush() on MSDN and it recommends flushing the (stdin) before using a stdin function because the previous stdin function might of overran the buffer. fflush() will clear the contents of this buffer.[/green]
    : :
    :
    : Microsoft does not set the ANSI standards. Yes, their compiler allows fflush(stdin), but most others do not. And Microsoft compilers are notorious for not being ANSI compliant in many other areas too.
    :
    :
    :


    [green]
    The compilers might not but I don't think that would matter since the stdin is handled by the OS right? What does the standards say about it? I'm curious to know.
    [/green]

  • : : [b][red]This message was edited by stober at 2005-7-14 11:54:8[/red][/b][hr]
    : : : [green]
    : : : I looked up fflush() on MSDN and it recommends flushing the (stdin) before using a stdin function because the previous stdin function might of overran the buffer. fflush() will clear the contents of this buffer.[/green]
    : : :
    : :
    : : Microsoft does not set the ANSI standards. Yes, their compiler allows fflush(stdin), but most others do not. And Microsoft compilers are notorious for not being ANSI compliant in many other areas too.
    : :
    : :
    : :
    :
    :
    : [green]
    : The compilers might not but I don't think that would matter since the stdin is handled by the OS right? What does the standards say about it? I'm curious to know.
    : [/green]

    [red]edit[/red]

    [green]
    I found the standard on fflush(). It doesn't say anything about stdin streams but it does mention output streams.
    [/green]

    [b]
    7.19.5.2 The fflush function
    Synopsis
    1 #include
    int fflush(FILE *stream);
    7.19.5.2 Library 269ഊISO/IEC 9899:1999 (E) ISO/IEC
    Description
    2 If stream points to an output stream or an update stream in which the most recent
    operation was not input, the fflush function causes any unwritten data for that stream
    to be delivered to the host environment to be written to the file; otherwise, the behavior is
    undefined.
    3 If stream is a null pointer, the fflush function performs this flushing action on all
    streams for which the behavior is defined above.
    Returns
    4 The fflush function sets the error indicator for the stream and returns EOF if a write
    error occurs, otherwise it returns zero.
    [/b]
  • [b][red]This message was edited by stober at 2005-7-14 12:45:36[/red][/b][hr]
    : [green]
    : I found the standard on fflush(). It doesn't say anything about stdin streams but it does mention output streams.
    : [/green]
    :
    : [b]
    : 7.19.5.2 The fflush function
    : Synopsis
    : 1 #include
    : int fflush(FILE *stream);
    : 7.19.5.2 Library 269ഊISO/IEC 9899:1999 (E) ISO/IEC
    : Description
    : 2 If stream points to an output stream or an update stream in which the most recent
    : operation was not input, the fflush function causes any unwritten data for that stream
    : to be delivered to the host environment to be written to the file; otherwise, the behavior is
    : undefined.
    : 3 If stream is a null pointer, the fflush function performs this flushing action on all
    : streams for which the behavior is defined above.
    : Returns
    : 4 The fflush function sets the error indicator for the stream and returns EOF if a write
    : error occurs, otherwise it returns zero.
    : [/b]
    :

    [red]otherwise, the behavior is undefined. [/red]
    [blue]that's whay fflush(stdin) has undefined behavior.[/blue]


  • [b][red]This message was edited by shaolin007 at 2005-7-14 13:0:48[/red][/b][hr]
    [red]otherwise, the behavior is undefined.
    that's whay fflush(stdin) has undefined behavior.
    [/red]

    [green]
    Ahh, I misread that part. I thought they were still talking about output streams. Anyways, I guess it works with the MS msvcrt.dll Windows OS and nothing else. One thing though, why would MS in the example on MSDN say this in thier code though?


    [code]
    fflush( stdin ); // fflush on input stream is an extension to the C standard
    [/code]
    It says extension to C standard. I don't see that extension in my ANSI doc. Do you have that section and could post it?
    [/green]



  • [green]: It says extension to C standard. I don't see that extension in my ANSI doc. Do you have that section and could post it?
    : [/green]

    that's why its called an extension -- because it is not in the ANSI doc.
  • [red]
    that's why its called an extension -- because it is not in the ANSI doc.
    [/red]

    [green]
    Confusing language in my opinion. When I think of extension, I think of a part of something that has expanded, but in this case I guess I am wrong. Either way I believe, we have both strayed from the original topic which is not beneficial to the original poster.
    [/green]

  • : [green]
    : Confusing language in my opinion. When I think of extension, I think of a part of something that has expanded, but in this case I guess I am wrong. Either way I believe, we have both strayed from the original topic which is not beneficial to the original poster.
    : [/green]
    :
    :

    I find the conversation interesting, but you are right: it doesn't really help me solve my problem:
    Why does _cgets() fail? Or, if that cannot be answered:
    What function do I use for user input?

    Thanks for all the replies anyway... Guess Microsoft decided to 'expand' the C standard...

    Greets...
    Richard

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories