1

I am trying to write a while-loop that terminates at the end of file. I have used while(!feof(stdin)) in the code bellow, but the loop doesn't seem to terminate even if EOF is reached (I am reading from file). When executed in terminal, the program does all that is supposed to, but then keeps going for several seconds before "program.exe stopped working" window opens. I have googled for almost several hours, tried different versions (variations for while (1) followed by int check = scanf("%d", &from); if (check == EOF) break;) and nothing worked for me.

The possibly problematic part of code:

while(!feof(stdin))
{
    check2 = scanf(" %d %d", &from, &to);
// some input checks with check2
    lcm1 = useky[from];

    if (from != (to-1))  
    {
        for (i = (from+1); i < to; i++) 
        {
            lcm2 = useky[i];
            lcm_temp = lcm_vypocet(lcm1,lcm2);
            lcm1 = lcm_temp;
        }       
    }
    printf("Vozidel: %lld\n", lcm1);
}

The entire code:

long long int lcm_vypocet(long long int x, long long int y) {
long long int a, b, t, gcd, lcm;

a = x;
b = y;

while (a != 0) {
t = a;
a = b % a;
b = t;
}

gcd = b;
lcm = x*(y/gcd);

return lcm;
}    

int main(int argc, char *argv[]) {

int i=0, check, check1=0, check2, highestIndex, from, to;    
int *useky, *useky_copy, *temp;
long long int lcm1, lcm2, lcm_temp;
char delimiter, check0;

printf("Pocty pruhu:\n");
useky = (int*) malloc(sizeof(*useky));
useky_copy = useky;

scanf("%1s", &check0);
if (check0!='{') 
{
    printf("Nespravny vstup.\n");
    exit(0);
}

for (i=0;;i++) 
{
    check = scanf(" %d %1s", &useky[i], &delimiter);
    highestIndex = i;

    if (check1==2) // break from the loop on end of input 
    {
        break;  
    }
    temp = (int*)realloc (useky, sizeof(*useky) + sizeof(int)); 
    if ( temp == NULL ) 
    {
        free(useky);
        printf("Nespravny vstup.\n");
        return 1;   
    }
    useky = temp;
}
printf("Trasy:\n");

while(!feof(stdin))
{
    check2 = scanf(" %d %d", &from, &to);
    lcm1 = useky[from];

    if (from != (to-1))  
    {
        for (i = (from+1); i < to; i++) 
        {
            lcm2 = useky[i];
            lcm_temp = lcm_vypocet(lcm1,lcm2);
            lcm1 = lcm_temp;
        }       
    }
    // lcm1 je výsledný počet vozidel.
    printf("Vozidel: %lld\n", lcm1);
}

free(useky_copy);   

return 0;
}

Does anyone have any tip for what might be wrong? I will really appreciate any help!

VerS
  • 11
  • 1
  • 4
    `while(!feof())` is **always a bug** because EOF is only detected **after** I/O, not before. Maybe read the comp.lang.c FAQ? http://c-faq.com/stdio/feof.html – Jens Dec 17 '17 at 19:03
  • 5
    Please read [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong) – Some programmer dude Dec 17 '17 at 19:04
  • 1
    Any tip? It sounds trite, but to read the man page for functions you are new to. – Weather Vane Dec 17 '17 at 19:06
  • Point of detail `if (check1==2)` will never be true, since `int check1=0` is only set when defined. It's good to see you using the return value from `scanf` but it is a bit hit and miss. – Weather Vane Dec 17 '17 at 19:10
  • Test your actual i/o operations for errors, not after the fact. https://stackoverflow.com/questions/20034876/c-read-scanf-until-feofstdin-dont-output-error – Retired Ninja Dec 17 '17 at 19:15
  • `check = scanf(" %d %1s", &useky[i], &delimiter); .... if (check1==2)` --> Certainly code should be assigning and checking the same variable here. – chux - Reinstate Monica Dec 17 '17 at 20:15
  • `char check0; ...scanf("%1s", &check0);` is bad code as `scanf("%1s"...` will attempt to save a character and a null character into insufficient memory. – chux - Reinstate Monica Dec 17 '17 at 20:17
  • 1
    `check2 = scanf(" %d %d", &from, &to); // some input checks with check2` --> Do not use `from` unless `check2 >= 1`. Do not use `to` unless `check2 >= 2`. – chux - Reinstate Monica Dec 17 '17 at 20:19
  • 1
    Thank you everyone. I know the code is still not very nice, but I managed to get rid of the bug (`while (fscanf(stdin," %d %d", &from, &to) != EOF)`). – VerS Dec 17 '17 at 22:17
  • for ease of readability and understanding: 1) consistently indent the code: indent after every opening brace '{'. unindent before every closing brace '}'. Suggest each indent level be 4 spaces. 2) separate code blocks (for, if, else, while, do...while, switch, case, default) via a single blank line. 3) follow the axiom: *only one statement per line and (at most) one variable declaration per statement.* – user3629249 Dec 18 '17 at 05:12
  • when calling any of the heap allocation functions: (malloc, calloc, realloc) 1) always check (!=NULL) the returned value to assure the operation was successful. 2) the returned type is `void*` which can be assigned to any pointer. Casting just clutters the code, making it more difficult to understand, debug, etc. – user3629249 Dec 18 '17 at 05:14
  • when calling any of the `scanf()` family of functions, always check the returned value (not the parameter values) to assure the operation was successful. – user3629249 Dec 18 '17 at 05:15
  • when the parameters for `main()` are not going to be used, then use the signature: `int main( void )`. When compiling, always enable the warnings, then fix those warnings. (for `gcc`, at a minimum, use: `-Wall -Wextra -Wconversion -pedantic -std=gnu11` ) – user3629249 Dec 18 '17 at 05:16
  • the posted code does not compile! It is missing the needed `#include` statements for the needed header files. (do you expect us to guess as to which (if any) header files the posted code is actually including?) – user3629249 Dec 18 '17 at 05:18
  • for ease of readability and understanding: insert appropriate horizontal spacing: inside parens, after commas, after semicolons, around C operators. – user3629249 Dec 18 '17 at 05:21
  • regarding: `while(!feof(stdin))` never works. suggest replacing `while(!feof(stdin)) { check2 = scanf(" %d %d", &from, &to);` with: `while( 2 == scanf(" %d %d", &from, &to) )` – user3629249 Dec 18 '17 at 05:23
  • when outputting an error message, it should be output to `stderr`, not `stdout` via something similar to: `fprintf( stderr, "...\n", ... )` However, when the error is from a system function, the text indicating why the system thinks the error occurred should also be output. Suggest using: `perror()` as that outputs to `stderr` and includes the text related to the `errno` value – user3629249 Dec 18 '17 at 05:27
  • regarding: `if (check1==2)` Nothing has updated the value in `check1` so the value will depend on what ever trash was on the stack where the variable is located. Perhaps you meant: `if (check==2)` however, that means the prior call to `scanf()` was successful, NOT that the end of file was reached. – user3629249 Dec 18 '17 at 05:33
  • it is considered poor programming practice to have several (especially unrelated) variables those names only differ by some digit value – user3629249 Dec 18 '17 at 05:35
  • it is best practice to limit the 'scope' of variables to where they are used rather than declaring all the variables at the beginning of a function. – user3629249 Dec 18 '17 at 05:38
  • regarding: `lcm = x*(y/gcd);` these are all integer values, so the math will be integer math. In the current scenario, the result will usually be 0. Probably not what you want. – user3629249 Dec 18 '17 at 05:40

0 Answers0