这是一个文件复制程序。
#include <stdio.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <stdlib.h>
int main()
{
int fd1,fd2, ndata;
char data[128];
char *openname[1], *creatname[1];
write(1, "Write open file name\n", 24); //user input
read(0, openname, 30 );
write(1, "Write creat file name\n", 25); //user input
read(0, creatname,30);
if((fd1 = open(openname, 0666))<0)
{
perror("cannot open the file");
exit(1);
}
if((fd2 = creat(creatname,0666))<0)
{
perror("cannot create the file");
exit(1);
}
while((ndata = read(fd1, data, 128))>0)
{
if((write(fd2, data, ndata))!=ndata)
{
perror("cannot write the file");
exit(1);
}
}
close(fd1);
close(fd2);
write(1, "File copy is done.",19);
return 0;
}
此代码无效。此代码打印错误消息:
cannot open the file.
但如果我将代码更改为:
if((fd1 = open("copy.c", 0666))<0)
和此:
if((fd2 = creat("real.c",0666))<0)
运作良好。
为什么会出现这种错误?请回答。
答案 0 :(得分:2)
您对openname
和creatname
的声明不正确。他们应该是:
char openname[31], creatname[31];
read()
不会在输入中添加空终止符,您需要添加它。 read()
返回读取的字节数。所以它应该是:
int nread = read(0, openname, sizeof openname -1);
openname[nread-1] = '\0'; // subtract 1 to overwrite the newline
答案 1 :(得分:1)
openname
和creatname
的类型错误,而gcc -Wall -g
会警告您。声明例如char openname[256];
您应该使用fgets(openname, sizeof(openname), stdin);
来阅读它。
如果您坚持使用read
,请处理换行符(如果有)并添加零终止字节。
还要学习使用gdb
调试器。
答案 2 :(得分:1)
read
级别很低。在这种情况下,它读取30个字节,包括您的回车键,也没有终止空字节。因此,文件名不会是您认为已经输入的内容,它将包含额外的垃圾(甚至可能因为缺少空终止而导致程序崩溃)。您想使用fgets
or readline
instead。
答案 3 :(得分:1)
简而言之,通过使用read()
来输入文件名,你自己就不必要了:它不会终止输入NUL,不能保证读取你期望的字符数,等
我的建议是坚持scanf()
或fgets()
。