在学习 Linux 操作命令之后,我们知道了在 Linux 终端可以使用 cp 命令来拷贝一个文件。
现在,我们通过 C 语言来制作一个自己的 cp 命令实现文件的拷贝。
1、main 函数的形参
编写代码之前,需要先了解一下 main 函数的形参,通过 main函数的形参可以获取命名行输入的参数。
main 函数有一种固定的形参格式,如下所示:
int main(int argc, char *argv[]);
- int argc:表示命令行参数的数量,程序名字本身算一个参数
- char *argv[]:命令行参数的字符串数组,表示参数具体内容
通过如下示例,可以快速了解 main 函数形参的使用方法:
#include <stdio.h>
int main(int argc, char* argv[]){
for(int i=0; i<argc; i++){
printf("%s\n", argv[i]);
}
return 0;
}
使用 gcc 进行编译,并运行编译后的文件:
由此可知,形参 char* argv[]={"test.exe", "hello", "world", "abc"},我们可以通过 argv 得到拷贝文件的路径。
2、编写C文件
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#define SIZE 1024*1024
int main(int argc, char* argv[]){
// 当接收到的参数数量不为3时,报错
if(argc != 3){
printf("参数数量错误\n");
return -1;
}
// fp1 指向被拷贝的原文件,fp2 指向拷贝后的目标文件
FILE* fp1 = fopen(argv[1], "rb");
FILE* fp2 = fopen(argv[2], "wb");
// 如果文件打开失败,报错
if(!fp1 || !fp2){
printf("文件复制失败\n");
return -2;
}
char* temp = NULL; // 存放每次从fp1中读取出的内容
int size = 0; // 每次从fp1中读取的字节数大小
struct stat st; // stat是用于获取文件状态的结构体
stat(argv[1], &st); // 获取原文件的状态信息,st的st_size成员保存了原文件的字节大小
// 根据文件的实际大小开辟空间(该空间大小为每一次从原文件读取的字节数)
if(st.st_size > SIZE){
// 当文件大小大于预先定义的大小时,使用预先定义的大小
temp = (char*)malloc(sizeof(char) * SIZE);
size = SIZE;
}else{
// 当文件小于预先定义的大小时,使用文件的实际大小+10(加10是为了保存字符串的结尾标志 \0 等信息)
// 当文件较小时,使用文件实际大小可以节省内存
temp = (char*)malloc(sizeof(char) * st.st_size + 10);
size = st.st_size + 10;
}
int count = 0;
while(!(feof(fp1))){
memset(temp, 0, size); // 将temp指向的空间内容设置为0
count = fread(temp, sizeof(char), size, fp1); // 从原文件中读取 sizeof(char)*size 大小的内容,保存在temp中,返回读取的数据块数
fwrite(temp, sizeof(char), count, fp2); // 将temp中的内容写入目标文件中,写入大小为 sizeof(char)*count
}
free(temp);
fclose(fp1);
fclose(fp2);
return 0;
}
通过该代码,就可以实现将原文件的内容全部拷贝到目标文件中。
下面,我们编译并使用该代码实现文件的拷贝。
拷贝成功!