【问题标题】:redirect stdout to file - in C将标准输出重定向到文件 - 在 C 中
【发布时间】:2017-10-05 13:59:23
【问题描述】:

我一直在尝试使用函数将输出重定向到文件并从文件而不是标准输入中读取,但是当我重定向到文件并检查文件是否已被用输出创建,那里什么都没有。这个函数有什么问题。

 /* Redirect a standard I/O file descriptor to a file
     * Arguments:   filename    the file to/from which the standard I/O file
     *              descriptor should be redirected
     *      flags   indicates whether the file should be opened for reading
     *          or writing
     *      destfd  the standard I/O file descriptor which shall be
     *          redirected
     * Returns: -1 on error, else destfd
     */
    int redirect(char *filename, int flags, int destfd){

            int ret;

            if(flags == 0){
                destfd = open(filename,O_RDONLY);

                if (destfd < 0){
                    return -1;
                }
                ret = dup2(0,destfd);

                if(ret < 0){
                return -1;
            }
               close(destfd);
            }

            if(flags == 1){
               destfd = open(filename,O_APPEND|O_WRONLY);

            if (destfd < 0){
                    return -1;
            }

            ret = dup2(destfd,1);

            if(ret < 0){
                return -1;
            }
            close(destfd);
            }
            return destfd;
        }

【问题讨论】:

  • 为什么destfd 是函数的参数?

标签: c unix redirect pipe file-descriptor


【解决方案1】:

你的代码有几个问题,尤其是非常糟糕的格式,这使得它很难阅读。

例如,对 dup2 的调用是反向调用 - 它用 stdin 的副本替换最近打开的 destfd

ret = dup2(0,destfd);

几行之后你关闭destfd

您的if 语句可以从您了解elseelse if 中受益

if(flags == 0) {
// code
} else if(flags == 1) {
// code
}

确实,尽管您可以通过将flags 参数视为与您传递给open 相同的标志并将destfd 作为您要替换的文件描述符来简化整个函数。

int redirect(char *filename,int flags, int destfd)
    {
    int fd;

    fd=open(filename,flags,S_IRUSR|S_IWUSR);
    if(fd!=-1)
        {
        if(dup2(fd,destfd)==-1)
            {
            close(fd);
            fd=-1;
            }
        else
            {
            close(fd);
            }
        }
    return fd;
    }

那么你可以这样称呼它

redirect("output.txt",O_CREAT|O_WRONLY,1); // Redirect stdout
redirect("input.txt",O_RDONLY,0); // Redirect stdin

【讨论】:

  • 或者甚至使用STDOUT_FILENOSTDIN_FILENO在最后一次调用中代替1和0。
【解决方案2】:

os 函数 dup2() 应该提供你需要的东西(如果没有引用你需要的东西)。

更具体地说,您可以 dup2() 将标准输入文件描述符复制到另一个文件描述符,使用标准输入执行其他操作,然后在需要时将其复制回来。

dup() 函数复制打开的文件描述符。具体来说,它使用 F_DUPFD 常量命令值为 fcntl() 函数提供的服务提供替代接口,其中第三个参数为 0。复制的文件描述符与原始文件描述符共享任何锁。

成功后,dup() 会返回一个新的文件描述符,它与原始文件描述符具有以下共同点:

相同的打开文件(或管道) 相同的文件指针(两个文件描述符共享一个文件指针) 相同的访问模式(读、写或读/写)

我所说的一切都可以在the manpage of dup上找到

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多