给定一个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的内容。
我错过了什么?
3条答案
按热度按时间7hiiyaii1#
Clang的gcc很好地指出了这个问题:
...特别地,
fdd
被设置为(open(...) == -1)
的结果,即如果open()
调用返回-1
,则设置为1
,或者如果open()
调用返回任何其它值,则设置为0
。由于0
和1
都不是open()
返回的文件描述符的值,对write(fdd, ...)
的后续调用使用了无效的文件描述符值,因此失败。修复方法是像第一次调用/open-for-read
open()
时那样添加括号,使其如下所示:除此之外,还需要将
O_WRONLY
添加到第二次调用open()
的oflag
参数中,否则将不允许fdd
写入文件。fykwrbwg2#
您忘记了一些括号,因此
fdd
被设置为0或1,而不是open
的返回值。将其与fdo
代码进行比较。最好避免在表达式中进行赋值,除非您确实知道自己在做什么。这也是在简化代码时首先要删除的内容之一,以便为堆栈溢出创建一个最小的完整可验证示例。b5lpy0ml3#
行中:
你把赋值放在括号里。这首先把打开的文件描述符赋值给
fdo
,然后检查该值是否等于-1。另一方面,在第二种情况下:
您没有将赋值放在方括号中。因此,首先计算
==
运算符,它返回值0(假)或1(真),而不是有效的文件描述符。然后将此值赋给fdd
,导致您写入错误的文件描述符(标准输出)。