我正在学习流并从教科书中复制了以下应用程序。当我的朋友在他的 Windows 机器上编译并运行时,它运行良好。当我在 Ubuntu 18.04 机器上运行应用程序时,输入工作正常,但这些值似乎对应用程序没有任何影响,即输入0不会导致程序退出。我的输出在代码下方。
在不同的机器上编译时什么会导致不同的行为,为什么这在我的机器上不起作用?
int main(int argc, char* argv[])
{
文件 *fpt;
字符字节;
long int where,move;
如果(argc != 2)
{
printf("用法:fileseek 文件名\n");
返回(0);
}
fpt = fopen(argv[1], "r");
如果(fpt == NULL)
{
printf("无法打开文件 %s 进行读取\n", argv[1]);
返回(0);
}
同时(1)
{
where = ftell(fpt);
fread(&byte,1,1,fpt);
fseek(fpt,-1,SEEK_CUR);
printf("Byte %d: %d (%c)\n", where, byte, byte);
printf("输入#bytes (+ or -) 移动,或 0 退出:");
scanf("%d", &move);
printf("移动:%d\n",移动);
如果(移动== 0)
休息;
fseek(fpt,move,SEEK_CUR);
}
fclose(fpt);
}
输出
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
Run Code Online (Sandbox Code Playgroud)
如果这正是它所说的,那么教科书是错误的:%d是 an 的转换说明符int,但move是long int. 正确的调用是:
scanf("%ld", &move)
Run Code Online (Sandbox Code Playgroud)
,对几个printf调用进行了类似的更正。
它可以通过巧合工作,尤其是在long和int碰巧是相同的大小(因为它们是在64位的Windows,但不能在64位Linux)。然而,由于不匹配,没有为整个程序定义特定的行为:语言标准允许编译器假设它们所代表的非法行为永远不会发生,并且对于执行这种行为的程序没有任何义务一个动作可以做。