来自freopen()和溪流的奇怪行为

时间:2013-10-17 15:15:22

标签: c stream freopen

编辑:我已经设法缩小了问题的范围,但对我来说仍然没有多大意义。我的代码变成8行:

int savedOut = dup(1);   
printf("Changing the outstream to process.txt!")
if ( freopen("process.txt", "w"m stdout) == NULL)
    printf("FREOPEN() FAILURE")
printf("Print to File\n");
dup2(savedOut, 1);
printf("Done with print to file");
return 1;

此代码将所有内容打印到终端。使用“savedOut”删除两行会将所有内容打印到process.txt。我理解后者的结果,但我不理解前者。

结束编辑

我在使用freopen()时遇到了很多困难。拿这段代码:

    int savedIn = dup(0);
    int savedOut = dup(1);

    while(1)
    {       
        readFile[0] = '\0';
        writeFile[0] = '\0';    
        dup2(savedIn, 0);
        dup2(savedOut, 1);

        if(getInputFlag == 1)
        {
            printf("myshell$ ");
            gotInputFlag = getUserInput(arguments, command, readFile, writeFile, catOrApp, bkgdFlag);
        }
        else
        {
            gotInputFlag = getUserInput(arguments, command, readFile, writeFile, catOrApp, bkgdFlag);
        }


        if(gotInputFlag == 1)
        {       

            history[historySize] = (char*)malloc(sizeof(char) * 1000);

            if (writeFile[0] != '\0' && *catOrApp == 0)
            {
                printf("Changing the outstream!\n");
                freopen(writeFile, "w", stdout);
            }

            printf("Print to File\n");                  

            dup2(savedIn, 0);
            dup2(savedOut, 1);

              printf("Done with print to file!\n");

                    ...

该程序将执行并打印“更改流程!”正如预期的那样。 “打印到文件!”永远不会打印到终端或writeFile。 “完成打印到文件!\ n”也不打印。稍后在代码中,代码在Hello World程序上调用execv(),该程序按预期打印到终端。但是,在程序终止时,所有printf语句都会打印到终端,甚至是“打印到文件”语句。

单个fgets()保存,getUserInput()不适用于流。

我不能为我的生活理解为什么会这样。有没有人有任何想法?

1 个答案:

答案 0 :(得分:0)

我认为这是与流缓冲相关的全部内容。你开始用stdout指着你的终端。因为它是字符设备,所以流是行缓冲的。您打印Changing the outstream to process.txt! 而不使用新行,以便文本保留在缓冲区中。你现在重新打开stdout到一个文件;流切换到完全缓冲。然后打印Print to File\n,尽管有新行,它仍保留在缓冲区中。

现在使用dup2将stdout更改回终端。但是,这适用于作为流的基础的fd。流库代码不知道此更改并使流完全缓冲。您再次打印并退出,将流刷新到fd(现在是您的终端)。

在每个fflush之后添加printf来电,我敢打赌你会看到你期望的行为。