如何使用 open() 和 printf() 写入文件?

How to write to a file using open() and printf()?

我正在使用 open() 打开一个文件,并且需要使用 printf 打印到该文件而不向控制台输出。我该怎么做呢?我可以成功创建文件,并将 printf 打印到控制台,但这是不正确的。

int main(int argc, char *argv[]) {
    int fd;
    char *name = "helloworld";
    fd = open(name, O_CREAT);

    char *hi = "Hello World";
    printf("%s\n", hi);

    close(fd);
    exit(0);
}

我需要程序没有输出到控制台,但如果我查看文件helloworld,它应该在里面写着"Hello World"。如:

prompt> ./hello
prompt> more helloworld
   Hello World

如果你用 open() 打开一个文件,你会得到一个 int 文件描述符,你可以用 write().

写入它

如果你用 fopen() 打开一个文件,那么你会得到一个 FILE* 句柄并且可以使用 stdio 函数族来写入它,其中包括 fprintf()fputs().

这是两个不同的抽象层次。 open()printf() 家族的关系不佳。您可以让它们与 fdopen() 一起工作,但混合抽象并不是一个好主意。

这是有技巧的。

您需要将打开的文件描述符复制到文件描述符1,即stdout。然后你可以使用 printf:

int main(int argc, char *argv[]){

    int fd;
    char *name = "helloworld";
    fd = open(name, O_WRONLY | O_CREAT, 0644);
    if (fd == -1) {
        perror("open failed");
        exit(1);
    }

    if (dup2(fd, 1) == -1) {
        perror("dup2 failed"); 
        exit(1);
    }

    // file descriptor 1, i.e. stdout, now points to the file
    // "helloworld" which is open for writing
    // You can now use printf which writes specifically to stdout

    char *hi = "Hello World";
    printf("%s\n", hi);

    exit(0);

}

您可以在使用 printf 之前关闭标准输出,这样输出将保存在您打开的文件目录中,而不是打印到控制台。

close(1); // close(STDOUT_FILENO);
fd = open(name, O_CREAT);

char *hi = "Hello World";
printf("%s\n", hi);

close(fd);

我假设 printf() 命令一次只能将输出打印到一个目录,如果您不先关闭它,它将转到默认的标准输出目录。如果您找到了一种在不关闭 STDOUT_FILENO 的情况下将输出目录设置为 fd 的方法,请告诉我。

如果你使用fopen来处理这个问题,一个更简单的技巧是使用variadic macros,这样你就可以在预处理中将printf替换为fprintf... 表示宏中的可变参数,就像它在带有可变参数的函数声明中的对应物一样。这个技巧适用于 C 和 C++。例如:

#include <stdio.h>
#define printf(...) fprintf(File, __VA_ARGS__)

int main()
{
    FILE *File;

    File = fopen("file.txt", "w+");

    printf("Hello world!");

    fclose(File);

    return 0;
}

注意:使用变参宏是因为printf的参数个数是一个变量