1.基本要求,实现文件的复制。编写程序实现cp命令的功能,程序源文件名为mycp.c,使用方法为:
./mycp 源文件名 目标文件名
2.扩展要求,当目标文件已存在时,给出提示是否进行覆盖,并根据用户的回应进行相应的操作。
3.扩展要求,在上一步实现功能的基础上,为mycp增加选项,如果选项为-f
,则当目标文件已存在时,不发出提示信息。
#include
#include
#include
#include
#include
#include
#include
#define ssize_t long long
int main(int argc, char *argv[])
{
// 基本要求:检查命令行参数
if (argc < 3)
{
fprintf(stderr, "wrong usage! you shoule input like:\n.\\mycp sourceFileName destinationFileName [-f]");
exit(1);
}
char *source_file = argv[1];
char *destination_file = argv[2];
// 1. 首先判断文件是否存在
int alreadyExist = access(destination_file, F_OK); /* access函数的作用,第二个参数可以是
R_OK 判断文件是否可读
W_OK 判断文件是否可写
X_OK 判断文件是否可执行
F_OK 判断文件是否存在
返回0则表示条件成立,-1则表示条件不成立
*/
// 2. 判断有没有-f参数
int force = (argc == 4 && strcmp(argv[3], "-f") == 0) ? 1 : 0;
// 3. 没有-f参数又已经存在文件则提示需不需要覆盖
if (!force && !alreadyExist)
{
char response[10];
printf("The destinationFile has existed!\nDo you want to overwirte the original file?(y/n): ");
fgets(response, sizeof(response), stdin);
/*
从第三个参数指定的流中读取最多第二个参数大小的字符到第一个参数指定的容器地址中。
在这个过程中,在还没读取够第二个参数指定大小的字符前,读取到换行符'\n'或者需要读取的流中已经没有数据了。
则提前结束,并把已经读取到的字符存储进第一个参数指定的容器地址中。
*/
if (response[0] != 'y' && response[0] != 'Y')
{
printf("exit.\n");
return 0;
}
}
// 4. 开始复制文件
// 打开源文件
int src_fd = open(source_file, O_RDONLY);
if (src_fd == -1)
{
fprintf(stderr, "can't open the source_file!\n");
exit(1);
}
int dest_fd = open(destination_file, alreadyExist ? O_WRONLY | O_CREAT : O_WRONLY | O_TRUNC);
/*
如果alreadExist为1,即文件不存在,则创建文件
如果alreadExist为0,即文件存在,则覆盖文件
*/
if (dest_fd == -1)
{
fprintf(stderr, "can't make the destination_file!\n");
close(src_fd);
exit(1);
}
int size = filelength(src_fd);
if (size > 10000)
{
fprintf(stderr, "the file is too large to cp!\n");
close(src_fd);
close(dest_fd);
exit(1);
}
// 读取源文件并写入目标文件
char buffer[10000];
ssize_t bytes_read;
while ((bytes_read = read(src_fd, buffer, sizeof(buffer))) > 0)
{
if (write(dest_fd, buffer, bytes_read) != bytes_read)
{
fprintf(stderr, "write error!\n");
close(src_fd);
close(dest_fd);
exit(1);
}
}
// 关闭文件描述符
close(src_fd);
close(dest_fd);
printf("successfully cp!\n");
return 0;
}
在使用gcc -o mycp mycp.c
编译生成 .exe
文件之后即可以正常使用
功能比较拉胯,仅供图一乐。
需要注意的是windows命令行默认的是GBK编码,所以代码内容最好不要有中文,不然会出现乱码