我有一个名为 abc
的程序.
当我运行以下命令时:
$ ./abc < infile
我得到以下输出:
ijklm
但是,当我运行时:
$ ./abc < infile > outfile
$ cat outfile
我得到了这个输出:
ijkoo
现在,我假设这是我程序的错误。但是,无论我的程序在做什么,我都不知道这是怎么可能的。
编辑:
现在我知道这是可能的,我很好奇我的程序中是什么导致了这种情况。
我的程序中的循环内有一个 block ,它包含:
byte = ascii_to_byte(asciibyte);
putchar(byte);
byte 的类型是 char
.
现在如果我改变 putchar(byte)
至 printf("%c", byte)
所有输出保持不变。
但是,如果我将其更改为 printf("%d", byte)
, 然后 $ ./abc < infile
输出:
105106107111111
这是 outfile
中那些 ascii 字符的十进制表示形式.但这不是字符的十进制表示,因为它们刚被发送到标准输出时实际出现。我不明白为什么会有这种差异。
编辑#2:
如果我将打印行更改为 printf("%c\n", byte)
, 然后 $ ./abc < infile
输出:
i
j
k
o
o
这与 outfile 中的内容一致。同样,不确定有什么区别。
编辑 #3
我刚刚在 32 位机器上测试了这个,程序运行:outputfile
包含 ijklm
.奇怪。
编辑 #4
这是主要功能:
int main()
{
char asciibyte[8];
char byte;
int c; //Using int to avoid the EOF pitfall.
long charcount = 0;
while((c = getchar()) != EOF){
if(c != '0' && c != '1'){
continue;
}
asciibyte[charcount % 8] = c;
if(charcount % 8 == 7){
/*Testing revealed that at this point asciibyte does contain
what it should contain, eight ASCII ones and zeros representing
a byte read in from stdin*/
byte = ascii_to_byte(asciibyte);
/*Print statements such as:
printf("%d", byte);
printf("%c\n", byte);
reveal that the ascii_to_byte function works incorrectly on my
64 bit machine. However these statements:
putchar(byte);
printf("%c", byte);
make it appear as though the function operates as it should.
EXCEPT if i redirect that output to a file.*/
putchar(byte);
}
charcount++;
}
return 0;
}
这是 ascii_to_byte 函数:
char ascii_to_byte(char *asciibyte){
char byte;
int i;
for(i = 0; i < 8; ++i){
if(asciibyte[7-i] == '1'){
byte = byte | (1 << i);
}
}
return byte;
}
最终编辑
我注意到我应该将字节初始化为 0x00。问题解决了。为什么我这么弱智?谁能具体说说这是怎么引起的,我就给出答案点。
最佳答案
这种奇怪的行为,根据看似无关的变化来来去去,可能表明您的程序不应该读取或写入内存,并且随着代码的其他部分对堆栈和/或堆。
我会仔细检查您的代码是否有问题,例如缓冲区溢出、返回指向堆栈变量指针的函数等。
使用调试器单步执行您的代码可能会很有成效(或者如果您不走运,它可能会再次改变行为!)。
您已经看到了一些有趣的事情:
stdout
的重定向如何可能影响任何事情?也许是因为它导致 C 库的行为有点不同:流使用不同的缓冲模式,具体取决于它是否连接到终端设备(参见 GNU libc documentation 或 C99 §7.9.13第 7 段)。为什么当
printf("% d", byte)
和printf("%c\n", byte)
会改变行为吗?可能是因为编译器自动将printf("%c", byte)
重写为更高效的putchar(byte)
- GCC 的最新版本通常会这样做,即使没有启用了优化 - 而printf("%d", byte)
和printf("%c\n", byte)
实际上将被编译为对的调用printf()
.
关于c - stdout 重定向更改输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6111660/