0
votes

Here's the situation, I have a code that reads values until the user inputs Ctrl+D, the problem though is I have to input it TWICE for it to successfully exit the loop, I figured it had to do with the fact that the Ctrl+D was being inserted into the string along with the remainings of the buffer and therefore didn't register as EOF and simply another character inside the string and only the second Ctrl+D which would be saved in an int variable, actually stopped the reading loop. To solve this I added while(getchar() != '\n') to see if it fixed the problem, but to no end. Here's my code:

typedef struct {
  char nome[50];
  int tempo;
  int ncertas;
} equipa;


int ler_equipas(equipa *resultados)
{
    int x, r1, r2 ,r3 ,r4, r11, r22, r33 ,r44, rcertas = 0, i = 0;
    scanf ("%d %d %d %d", &r1, &r2, &r3, &r4);
    while (scanf ("%s %d %d %d %d %d", resultados[i].nome, &resultados[i].tempo, &r11, &r22, &r33, &r44 ) == 6 )
    {
        i++;
        if (r1 == r11) rcertas++;
        if (r2 == r22) rcertas++;
        if (r3 == r33) rcertas++;
        if (r4 == r44) rcertas++;
        resultados[i-1].ncertas = rcertas;
        rcertas = 0;
        while((x=getchar()) != '\n');
    }
    return i;
}

The input/output was as follows (">>" means output):

1 2 3 4
>> correct answers are 1 2 3 4
Team1 234 1 2 3 4
>> values inputed for team time and answers: Team1 234 1 2 3 4
>> getchar value was (ASCII): 10
>> Next read:

Team2 400 1 3 2 4
>> values inputed for team time and answers: Team2 400 1 3 2 4
>> getchar value was (ASCII): 10
>> Next read:
>>
^D
^D
>> return i was reached
>> Number of teams: 2
>> Team "Team1" took 234 seconds and answered 4 questions correctly
>> Team "Team2" took 400 seconds and answered 2 questions correctly
2
I suggest getting return values of both scanf calls, as well as getchar call, to a variable, and then running your code under debugger (or adding debug prints) to see what those return, and how the code flow goes.hyde
Actually, as this isn't a complete program, and it seems the code should not have the bug you describe (it does have a few other serious problems, basically you don't check return values of scanf and getchar properly), it seems likely that the problem is in the part of the code you are not showing us...hyde
I have added a printf right before return i and it only printed after the double ctrl+D, I've also added printf's throughout the code to see if something wasn't being read properly, and everything seems to check out, the variables have the values they're supposed to have and getchar allways catches the newline character which in theory means the newline gets removed from the buffer, could it be a compiler problem?Carlos Pinto
Can't reproduce on my Linux. Which system do you use?4386427
I'm using Windows 10 Codeblocks, whatsoever this isn't the complete code, it's only a function, I figured the complete code would be too long, and this is the first function called in main() and prior to it only variable declaration was made, so I don't think it could be the causeCarlos Pinto

2 Answers

1
votes

Since you are using windows, you shall use ctrl+z for emulating EOF

See https://stackoverflow.com/a/16136924/4386427

When you use ctrl+d, the first ctrl+d matches the initial %s so the scan continues.

The second ctrl+d will not match %d so the scan terminates. Since the number of scanned elements isn't 6, the while loop terminates.

Consequently two ctrl+d terminates the function. A single ctrl+z will also terminate the program.

0
votes

I did not try this yet. But i remember having the same Problems...

Try this: How to clear input buffer in C?

while ((c = getchar()) != '\n' && c != EOF) { }

This is a way to clear the input buffer.
But this after a scanf(); call to clear the input Buffer.

Best regards