0

I have a program with alot of data stored in a file and gets loaded into structs.

I have an option so the user can change some information but since I don't know what he wants to change I need to printf and scanf all the information of the item he wants to change.

This is a part of the program:

char check;
    
if(p->vetor.id == jogo){
            
    printf("Reference: %d\n", jogo);
        fflush(stdin);
    printf("\nTeam 1: ");
        if(getchar() != '\n'){ // METHOD 1
            gets(p->vetor.eqTeam1); 
        }
        fflush(stdin);
        
    printf("\nTeam 2: ");
        if(scanf("%c", &check) && check != '\n'){ //METHOD 2
            gets(p->vetor.eqTeam2);
        }
        fflush(stdin);
}

It checks if the input is a ENTER (and it works) but when I write something there it "eats" the first letter because it needs to check before if is a ENTER or not, is there a way to give the lost letter back to the gets() ?

Thanks for your help.

Arty
  • 49
  • 5
  • Use an **else** in combination with your **if**. – paladin Jan 09 '21 at 17:17
  • 1
    Four things: a) Never use `gets()`, it is no longer part of the standard C library. Please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) b) you'll waste hours trying to get a mix of `gets()` or `fgets()` and `getchar()` with `scanf()` working - use only one method. c) The format specifier `"%c"` reads every character including newlines. Try `" %c"` with a space. d) `fflush()` is undefined for an input stream. – Weather Vane Jan 09 '21 at 17:20

2 Answers2

1

It checks if the input is a ENTER (and it works) but when I write something there it "eats" the first letter because it needs to check before if is a ENTER or not, is there a way to give the lost letter back to the gets() ?

The function ungetc() is probably what you're looking for.

However, cleaning input buffers is a recurrent topic in C. Be aware that fflush(stdin) is a Undefined Behavor, because it actually makes no sense : flushing a buffer doesn't drop its content, it actually triggers its immediate shipping toward its final destination, which is, in case of an input buffer… yourself !

Some systems take advantage of this non-defined behavour situation to actually drop it as expected (which is an undefined behavour just like anything else), but this is a trap because the programmer get used of doing something that is not supposed to work. To my eyes, the most consistent behavor here is to do nothing, since the buffer's content is already available to the reader.

Obsidian
  • 3,719
  • 8
  • 17
  • 30
0

Don't use scanf and never again use gets.

Your problem can be solved by just using fgets

printf("\nTeam 2: ");
fflush(stdout);
char input[256];  // same size of eqTeam
fgets(input, sizeof(input), stdin);
if (input[0] != '\n') {
    strcpy(p->vetor.eqTeam2);
}

This will always read in a full line, but if the first character of the line is a newline, the user just pressed enter. If the first char is something else, the input is copied to the correct location. Note that the input buffer must be of a suitable size, here I just guessed one that is for sure not correct (but I lack the necessary info)

And one more thing, never flush stdin, you have to fflush(stdout) as fflush is an output operation.

koder
  • 2,038
  • 7
  • 10
  • Thanks for helping me, at school they told use to use gets(), is it dangerous to use it for projects like this? – Arty Jan 09 '21 at 21:48
  • It is so dangerous it was removed from the standard. It has no way of specifying the size of the input buffer. You should forget it ever existed. – koder Jan 10 '21 at 10:21