0

编辑:我已经设法缩小问题的范围,但对我来说仍然没有多大意义。我的代码变成了 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”也不打印。稍后在代码中,代码调用execv()Hello World 程序,该程序按预期打印到终端。但是,在程序突然终止时,所有 printf 语句都会打印到终端,甚至是“打印到文件”语句。

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

我一生都无法理解为什么会这样。有人有什么主意吗?

4

1 回答 1

0

这就是我认为正在发生的一切都与流缓冲有关。您从指向终端的标准输出开始。因为它是一个字符设备,所以流是行缓冲的。Changing the outstream to process.txt! 您在没有换行符的情况下打印,因此文本保留在缓冲区中。您现在将标准输出重新打开到文件;流切换到完全缓冲。然后,尽管换行,您仍会打印Print to File\n保留在缓冲区中的内容。

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

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

于 2013-10-17T16:35:19.617 回答