【问题标题】:Copy content from one file to another in C在C中将内容从一个文件复制到另一个文件
【发布时间】:2022-11-24 00:25:38
【问题描述】:

给定一个 txt 文件,我试图制作一个 C 程序,将其内容复制到另一个名称由参数传递的文件中。该程序必须从源文件中读取 512 字节的块,并将读取的字节写入目标文件中。

我的尝试:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include<fcntl.h>

int main(int argc, char* argv[]){
    if(argc < 2){
        printf("ERROR: Missing arguments\n");
        exit(1);    
    }

    int fdo, fdd;

    if((fdo = open(argv[1], O_RDONLY)) == -1){
        printf("ERROR: Origin file %s can not be opened\n", argv[1]);
        exit(1);
    }

    if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1){
        printf("ERROR: Dest. file %s can not be opened\n", argv[2]);
        exit(1);
    } 

    char buff[512];
    size_t n_bytes;

    while((n_bytes = read(fdo,buff,512)) > 0){
        if(write(fdd,buff,n_bytes) < 0){
            printf("Can not write buffer content in %s \n", argv[2]);
            exit(1);
        }
    }

    if(n_bytes < 0){
        printf("Can not read %s file \n", argv[1]);
        exit(1);
    }

    close(fdo);
    close(fdd);

    return 0;
}

文件test.txt的内容为:

abcdef
1890

他们的权限是:

usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ ls -l
total 32
-rwxrwxr-x 1 usuarioso usuarioso 17048 nov 23 16:15 copyrf
-rw-rw-r-- 1 usuarioso usuarioso   774 nov 23 16:39 copyrf.c
-rw-rw-r-- 1 usuarioso usuarioso    12 nov 23 16:52 test.txt

但是,当我执行它时,我得到以下信息:

usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ gcc -o copyrf copyrf.c
usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ ./copyrf test.txt test1.txt
abcdef
1890
usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ ls -l
total 28
-rwxrwxr-x 1 usuarioso usuarioso 17008 nov 23 17:00 copyrf
-rw-rw-r-- 1 usuarioso usuarioso   771 nov 23 16:59 copyrf.c
-rw-rw-rw- 1 usuarioso usuarioso     0 nov 23 17:00 test1.txt
-rw-rw-r-- 1 usuarioso usuarioso    12 nov 23 16:52 test.txt
usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ cat test1.txt
usuarioso@usuarioso-virtualbox:~/Documentos/SO 2022/pr2/API de ficheros y directorios$ 

即文件 test1.txt 已创建但为空,文件 test.txt 的内容打印在控制台中。

我错过了什么?

【问题讨论】:

    标签: c linux file-descriptor


    【解决方案1】:

    您忘记了一些括号,所以 fdd 被设置为 0 或 1 而不是 open 的返回值。将其与 fdo 代码进行比较。除非您真的知道自己在做什么,否则最好避免在这样的表达式中赋值。这也是在简化您的代码以创建 Stack Overflow 的最小完整可验证示例时首先要删除的内容之一。

    【讨论】:

      【解决方案2】:

      Clang 的 gcc 很好地指出了这个问题:

      $ gcc temp.c
      temp.c:19:12: warning: using the result of an assignment as a condition without parentheses [-Wparentheses]
          if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1){
             ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      temp.c:19:12: note: place parentheses around the assignment to silence this warning
          if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1){
                 ^
             (                                                 )
      temp.c:19:12: note: use '==' to turn this assignment into an equality comparison
          if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1){
             ^
                 ==
      

      ...特别是,fdd 被设置为 (open(...)==1) 的结果,即如果 open() 调用返回 -1,则设置为 0,如果 open() 调用成功,则设置为 1。由于这些都不是open() 返回的文件描述符,您对write() 的调用使用了错误的文件描述符值。

      解决方法是像您对第二个/open-for-write open() 调用所做的那样添加括号,改为这样:

      if((fdd = open(argv[2], O_CREAT | O_TRUNC, 0666)) == -1){
      

      【讨论】:

        【解决方案3】:

        在行中:

        if((fdo = open(argv[1], O_RDONLY)) == -1)
        

        你把作业放在括号里。这首先将打开的文件描述符分配给fdo,然后检查该值是否等于 -1。

        另一方面,在第二种情况下:

        if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1)
        

        你没有把作业放在括号里。因此,首先评估 == 运算符,它返回值 0(假)或 1(真)而不是有效的文件描述符。然后将该值分配给fdd,导致您写入错误的文件描述符(标准输出)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-10
          • 1970-01-01
          • 2011-06-04
          • 1970-01-01
          相关资源
          最近更新 更多