1
votes

I am learning about streams and copied the following application from the text book. When my friend compiles and runs on his Windows machine, it works fine. When I run the application on my Ubuntu 18.04 machine, the input works fine, but the values don't seem to have any effect on the application, i.e. entering 0 does not cause the program to exit. My output is below the code.

What would cause different behavior when compiling on different machines, and why is this not working on my machine?

int main(int argc, char* argv[])
{
    FILE        *fpt;
    char        byte;
    long int    where,move;

    if(argc != 2)
    {
        printf("Usage: fileseek filename\n");
        return(0);
    }

    fpt = fopen(argv[1], "r");

    if(fpt == NULL)
    {
        printf("Unable to open file %s for reading\n", argv[1]);
        return(0);
    }

    while(1)
    {
        where = ftell(fpt);

        fread(&byte,1,1,fpt);
        fseek(fpt,-1,SEEK_CUR);

        printf("Byte %d: %d (%c)\n", where, byte, byte);
        printf("Enter #bytes (+ or -) to move, or 0 to quit: ");

        scanf("%d", &move);

        printf("move: %d\n", move);

        if(move == 0)
            break;

        fseek(fpt,move,SEEK_CUR);
    }
    fclose(fpt);
}

Output

jonathon@dev1:~/hoover/ch5/build$ ./fileseek  text.txt 
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 0
move: 0
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 1
move: 1
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 2
move: 2
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 3
move: 3
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 4
move: 4
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: 5
move: 5
Byte 0: 84 (T)
Enter #bytes (+ or -) to move, or 0 to quit: ^C     
1

1 Answers

5
votes

The textbook is wrong if it that’s exactly what it says: %d is a conversion specifier for an int, but move is a long int. The correct call would be:

scanf("%ld", &move)

, with similar corrections to several printf calls.

It can work by coincidence, especially when long and int happen to be the same size (as they are in 64-bit Windows, but not in 64-bit Linux). With the mismatches, however, no particular behaviour is defined for the entire program: the compiler is allowed by the language standard to assume that the kind of illegal actions they represent never happen, and has no obligation whatever as to what a program that performs such an action may do.