c - stdout 重定向更改输出

标签 c unix

我有一个名为 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。问题解决了。为什么我这么弱智?谁能具体说说这是怎么引起的,我就给出答案点。

最佳答案

这种奇怪的行为,根据看似无关的变化来来去去,可能表明您的程序不应该读取或写入内存,并且随着代码的其他部分对堆栈和/或堆。

我会仔细检查您的代码是否有问题,例如缓冲区溢出、返回指向堆栈变量指针的函数等。

使用调试器单步执行您的代码可能会很有成效(或者如果您不走运,它可能会再次改变行为!)。

您已经看到了一些有趣的事情:

  1. stdout 的重定向如何可能影响任何事情?也许是因为它导致 C 库的行为有点不同:流使用不同的缓冲模式,具体取决于它是否连接到终端设备(参见 GNU libc documentationC99 §7.9.13第 7 段)。

  2. 为什么当 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/

相关文章:

c - 将地址 int "p = &i"分配给指针 "*p = i"时, "i"和 "p"之间是否有任何差异

c++ 从标准输入快速读写

linux - 如何获取bash中每条记录的最小值和最大值

macos - 在终端中永久设置默认编辑器

java - ProcessBuilder java Unix 命令

c - 如何在数字中添加空格,以千为单位分组?

c++ - 如何在设备内存中有效地随机播放数据?

c - 从 C 中的函数传递和返回 2 个数组

仅检查 O_RDONLY 标志以打开 (2)

windows - 检测可执行文件是否存在于具有 Node 的系统路径上