将c语言中的内容从一个文件复制到另一个文件



给定一个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 argumentsn");
exit(1);    
}
int fdo, fdd;
if((fdo = open(argv[1], O_RDONLY)) == -1){
printf("ERROR: Origin file %s can not be openedn", argv[1]);
exit(1);
}
if(fdd = open(argv[2], O_CREAT | O_TRUNC, 0666) == -1){
printf("ERROR: Dest. file %s can not be openedn", 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的内容被打印到控制台。

我错过了什么?

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,则设置为1,如果open()调用返回任何其他值,则设置为0。由于01都不是open()返回的文件描述符的值,因此对write(fdd, ...)的后续调用使用了无效的文件描述符值,因此失败。

修复将是添加括号,你做了你的第一个/open-for-readopen()调用,使其像这样:

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

除此之外,您还需要将O_WRONLY添加到第二次调用open()oflag参数中,否则将不允许fdd写入文件。

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

行内:

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

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

另一方面,第二种情况:

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

你没有把赋值放在括号里。因此,首先计算==运算符,它返回0 (false)或1 (true)的值,而不是一个有效的文件描述符。该值随后被赋给fdd,导致您写入错误的文件描述符(标准输出)。

相关内容

  • 没有找到相关文章

最新更新