2

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 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

It can also work by coincidence when long and int are not the same, as it does for me on CentOS 8. It's quite right, though, that several of the field descriptors in the OP's code fail to match the corresponding arguments, that this produces undefined behavior, and that the OP's observed results are a plausible manifestation.
This is really disappointing to find in a text book.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.