C语言文件操作 (实现简易的Liunx cp命令)

多文件编程

当程序的业务逻辑越来越复杂、代码量越来越多时,所有代码写在一个源文件中会影响代码的编写、阅读,因此为了避免这些问题,可以按功能把代码编写在不同的文件中,然后给每个源文件编写一个辅助说明的头文件。
那么头文件中应该写什么呢?
1. 头文件卫士
2. 结构、联合、枚举的类型设计
3. 全局变量的声明,在对应的源文件中定义
4. 函数声明,在对应的源文件中实现
5. 宏常量和宏函数
注意:头文件中的内容能在不同的源文件中重复出现而不产生冲突
注意:源文件一定要包含自己对应的头文件,为了检查头文件中的函数声明与源文件中的函数定义是否匹配。

多文件编译

1.单独把每个源文件生成目标文件
gcc -c file.c -> file.o
2. 把生成的目标文件合并在一起,生成可执行文件
gcc a.o b.o c.o … -o 程序名
但当文件越来越多时,这样编译效率非常低,因此我们可以使用Makefile编译脚本进行批量编译。

Makefile文件的编写

首先Makefile编译脚本中记录的是项目编译指令的集合,通过make指令批量执行

#简单的Makefile示例\

CC=gcc #编译器
FLAG=-Wall -Werror
OBJS=a.o b.o c.o d.o e.o #要编译出的目标文件
TARGET=helloworld	#可执行程序

#定义编译目标
all:$(OBJS)
	$(CC) $(OBJS) -o $(TARGET)

# %是Makefile中的通配符
%.o:%.c
	$(CC) $(FLAG) -c $<

clean:
	rm -rf *.h.gch
	rm -rf $(OBJS)

#Makefile需要注意的语法标准\
1. 使用TAB键进行缩进,不要用空格\
2. 编译目标可以调用编译目标,也可以依赖文件\
3. Makefile会根据文件的最后修改时间判断是否需要重新编译.c文件\
4. 默认只执行第一个编译目标,可以通过Make命令手动调用编译目标。

文件读写

文件类型:
从编程角度我们把文件分为两大类,分别是文本文件和二进制文件。
二进制文件:存储的是数据的补码,无法用文本文件直接打开,好处是读取文件就可以直接使用。
文本文件:把数据以字符形式存储到文件中,可以被直接打开,检查数据是否正确,但读写都需要进行数据转换。

文件操作:
FILE* fopen(const char *path, const char *mode);
功能: 打开创建文件
path: 文件的路径
mode: 打开文件
“r” 以只读方式打开文件,如果文件不存在则打开失败
“r+” 在r的基础上增加写权限
“w” 以指定方式打开文件,如果文件不存在则创建,如果文件已经存在则清空文件内容。
“w+” 在w的基础上增加读权限
“a” 以只写权限打开文件如果文件不存在则创建,如果文件已经存在则新写入的内容添加到文件末尾。
“a+” 在a的基础上增加读权限
返回值:
FILE结构指针,该结构中记录着被打开文件的相关数据,它是接下来操作文件的凭证。如果文件打开失败,则返回NULL。

注意:如果文件本身没有相关权限,则会打开失败.
ls -l 查看文件权限
r读4 w写2 x执行1

int fclose(FILE* stream);
功能: 关闭文件指针
stream:关闭文件流
返回值:成功返回0,失败返回-1.

int fprintf(FILE *stream, const char *format, …);
功能:以文本格式写入数据到文件
stream:要写入的文件,fopen的返回值。
format:格式
…: 要写入的变量
返回值:成功写入的字节数

int fscanf(FILE *stream, const char *format, …);
功能:从文本文件中读取各类型的数据
stream:要读取的文件,fopen的返回值
format:占位符
…:存储数据变量的地址
返回值:成功读取变量的个数

size_t fwrite(const void *ptr, size_t size, size_t nmemb,FILE *stream);
功能:把内存的数据拷贝到文件中
ptr:要写入数据的内存首地址
size:数据每个元素的字节数 1
nmemb:元素的个数 1
stream:文件指针
返回值:成功写入的元素个数,正常情况下应该是nmemb参数

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:从文件拷贝数据到内存
ptr:存储数据的内存首地址
size:数据每个元素的字节数,1
nmemb:元素的个数
stream: 文件指针
返回值:成功读出的元素个数,正常情况下应该是nmemb参数

int fseek(FILE *stream, long offset, int whence);
功能:设置文件的位置指针
stream:要设置的文件
offset: 偏移值
whence:基础位置
SEEK_SET 开头
SEEK_CUR 当前
SEEK_END 末尾
返回值:成功返回0,失败返回-1
fseek(frp,0,SEEK_SET);

void rewind(FILE *stream);
功能:把文件的位置指针调整到开头

long ftell(FILE *stream);
功能:获取文件位置所指向的字节数

char *fgets(char *s, int size, FILE *stream);
功能:从文件中读取一行字符串,且可以限制字符串的长度

int remove(const char *pathname);
功能:删除文件

int rename(const char *oldpath, const char *newpath);
功能:重命名文件

int access(const char *pathname, int mode);
功能:测试文件权限
Mode:要测试的权限
F_OK 文件是否存在
R_OK 文件是否有读权限
W_OK 文件是否有写权限
X_OK 文件是否有执行权限
返回值:如果测试权限存在,则返回0,不存在则返回-1

实现Linux系统中的cp命令

#include <stdio.h>

int cp (const char* dest,const char* src);

int main(int argc,const char* src)
{
	cp(argv[1],argv[2]);
} 

int cp(const char* dest,const char* src)
{
	FILE* fsp = fopen(src,"r");
	FILE* fdp = fopen(desr,"w+");
	char tmp[255];
	int count = 0;
	
	if(NULL == fsp)
	{
		printf("文件打开失败!\n");
		return -1;
	}
	else
	{
		while(fread(tmp,1,1,fsp))
		{
			fwrite(tmp,1,1,fdp);
		}
	}
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值