【问题标题】:How to write to a file using open() and printf()?如何使用 open() 和 printf() 写入文件?
【发布时间】:2016-05-13 03:34:33
【问题描述】:

我正在使用 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

【问题讨论】:

  • 为什么不使用fprintf
  • 我必须使用 printf
  • freopen() 到标准输出?
  • open 是 POSIX 标准函数,而不是 C 标准库函数。您可以使用fopen 打开文件,然后使用fprintf 和标准库中的其他函数写入文件。
  • 你通过什么标志打开?第一次尝试时获得正确的标志集可能会很棘手。

标签: c file-io printf output


【解决方案1】:

如果您使用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的参数个数是一个变量。

【讨论】:

    【解决方案2】:

    您可以在使用 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 的方法,请告诉我。

    【讨论】:

      【解决方案3】:

      这有一个技巧。

      您需要将打开的文件描述符复制到文件描述符 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);
      
      }
      

      【讨论】:

      • 您应该删除close(fd)exit,甚至只是从main返回将导致stdoutfclose(stdout)关闭,这将fflush(stdout);。将内容刷新到文件中可能需要此步骤。关闭系统句柄可以防止这种情况发生。
      • @chqrlie 好电话。已编辑。
      • @user2877117:如果你还没有学过dup2,你可以在fd = open(name, O_WRONLY | O_CREAT, 0644);之前调用close(1);。在此之后很有可能fd == 1,您将不需要致电dup2(fd, 1);
      【解决方案4】:

      如果你用open() 打开一个文件,那么你会得到一个int 文件描述符,你可以用write() 写入它。

      如果您使用fopen() 打开一个文件,那么您将获得一个FILE* 句柄,并且可以使用stdio 系列函数对其进行写入,其中包括fprintf()fputs()

      这是两个不同的抽象级别。 open()printf() 家族不能很好地融合。您可以让它们与 fdopen() 一起工作,但混合抽象并不是一个好主意。

      【讨论】:

      • 作业指定使用 printf 和 open
      • @user2877117,看起来你的老师或创建作业的人有点误导。
      • 这对我没有帮助,我只是不知道如何进行
      • @user2877117:请教你的导师。他自己好像也糊涂了。他怎么能假设你有一个兼容 POSIX 的系统可用?该课程是否需要 Unix 或 Linux(OS-X?)? AFAIK Windows 前段时间放弃了对 POSIX 的支持。
      • 使用dup2重定向stdout
      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-02
      • 2017-10-22
      • 2015-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多