将stdout重定向到文件 - 在C中

时间:2017-10-05 13:59:24

标签: c unix redirect pipe file-descriptor

我一直试图通过使用函数将输出重定向到文件并从文件而不是stdin读取,但它似乎无法正常工作,因为我重定向到文件并检查是否有文件已经创建了输出,那里什么都没有。这个功能可能有什么问题。

 /* 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;
        }

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

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

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

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

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

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

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

找到