编码格式的调整:
visual stuio 中用的是GBK的编码,我们在Linux vim 里用的是 utf-8 编码。
vim 的末行模式下:
:set fileencoding=utf8 // 将文件修改为 utf-8 编码
概述:Makefile是文件编译工具,方便源文件编译成可执行文件。Makefile 是一个文本文件,一个包含了编译规则的文本文件。在项目中敲击一个命令:make ,即可完成编译。
文件命名:Makefile 或 makefile
编写规则
目标 : 依赖
由依赖生成目标的命令
书写Makefile
# $(wildcard 文件路径) 表示指定路径下的所有匹配文件
# 假设要获取当前路径下的所有.c文件
# $(wildcard ./*.c)
#
# $(patsubst 被替换模式,替换模式,进行操作的文件内容)
# 假设要将所有.c 替换成.o
# $(patsubst %.c,%.o,a.c b.c c.c)
srcs=$(wildcard ./*.c)
objs=$(patsubst %.c,%.o,$(srcs))
target=app
$(target) : $(objs)
gcc $^ -o $@ -I include/
# gcc $(objs) -o $(taregt) -I include/
%.o : %.c
gcc -c $< -o $@ -I include/
# .PHONY 指的该文件是一个虚拟文件,不需要创建出来这个文件,仅执行该目标文件下的命令
.PHONY:clean
clean:
rm $(target) $(objs)
srcs、objs、target都是定义变量,用来减少下面书写的代码,使用$(变量名)
在后面使用
表 示 上 面 规 则 中 的 全 部 依 赖 文 件 , ^ 表示上面规则中的全部依赖文件, 表示上面规则中的全部依赖文件,< 表示上面规则中的依赖文件中的第一个,$@ 表示目标文件
规则中的%表示可以匹配任意字符,例如:%.c 表示匹配任意名字的 .c 文件
注意:在Makefile规则中%表示通配,路径中*表示通配
Makefile中特有的函数(通俗理解为字符串操作函数)
$(wildcard 文件路径) 表示指定路径下的所有匹配文件
假设要获取当前路径下的所有.c文件$(wildcard ./*.c)
$(patsubst 被替换模式,替换模式,进行操作的文件内容)
假设要将所有.c 替换成.o $(patsubst %.c,%.o,a.c b.c c.c)
.PHONY:目标名
表示虚拟文件,即不需要创建出这个文件,仅执行目标文件下的命令
标准I/O与系统I/O的区别:
fopen与open的效率对比:
程序和文件:
程序运行时,会默认打开 3 个文件:标准输入文件、标准输出文件、标准错误文件。
open函数:
int open (const char *file, int oflag, ...)
头文件:
#include
#include
#include
当打开一个文件的时候,如果文件不存在则创建。Linux 中文件是有权限的,创建时候需要指定权
限。由 mode 参数指定文件权限。
int open(const char *pathname, int flags); 用于打开已经有的文件,不需要传递第三个参数。
mode 参数
int open(const char *pathname, int flags, mode_t mode);
如果文件不存在,要创建,则oflag 参数:
open 函数的打开模式中并没有区分文本模式和二进制模式:因为Linux系统函数仅在系统中使用,没有行结尾的相异
成功则返回文件描述符,失败则返回-1,此时 errno 会被设置为相应的错误码,使用 perror函数
可打印详细的错误描述。
write 函数
ssize_t write(int fd, const void *buf, size_t count);
include
read 函数
ssize_t read(int fd, void *buf, size_t count);
#include
close 函数
#include
#include
#include
#include
#include
#include
#include
void test01()
{
int fd;
fd = open("demo01.txt",O_WRONLY | O_CREAT,0777);
if(fd == -1)
{
perror("open");
return;
}
const char* data = "hello world\n";
int len = write(fd,data,strlen(data));
if(len == -1)
{
perror("write");
return;
}
int ret = close(fd);
if(-1 == ret)
{
perror("close");
return;
}
}
void test02()
{
int fd;
fd = open("demo01.txt",O_RDONLY);
if(fd == -1)
{
perror("open");
return;
}
char buf[128] = { 0 };
int len = read(fd,buf,128);
if(len == -1)
{
perror("write");
return;
}
printf("buf = %s",buf);
int ret = close(fd);
if(-1 == ret)
{
perror("close");
return;
}
}
int main()
{
//test01();
test02();
return 0;
}
lseek 函数可以实现移动文件指针,从而实现随机文件读写。
off_t lseek(int fd, off_t offset, int whence);
头文件:#include
#include
#include
#include
#include
#include
struct Person{
char name[32];
int age;
};
void test01()
{
struct Person persons[] = {
{"Obama",50},
{"Smith",60},
{"Trump",70}
};
int fd = open("person.txt",O_WRONLY | O_CREAT,0777);
if(-1 == fd)
{
perror("open");
return;
}
int len = write(fd,persons,sizeof(persons));
if(-1 == len)
{
perror("write");
return;
}
int ret = close(fd);
if(-1 == ret)
{
perror("close");
return;
}
}
void test02()
{
int fd = open("person.txt",O_RDONLY);
if(-1 == fd)
{
perror("open");
return;
}
struct Person p1;
int len = read(fd,&p1,sizeof(struct Person));
if(-1 == len)
{
perror("read");
return;
}
printf("Name:%s Age:%d\n",p1.name,p1.age);
int ret = lseek(fd,sizeof(struct Person),SEEK_CUR);
if(-1 == ret)
{
perror("lseek");
return;
}
struct Person p2;
len = read(fd,&p2,sizeof(struct Person));
if(-1 == len)
{
perror("read");
return;
}
printf("Name:%s Age:%d\n",p2.name,p2.age);
ret = close(fd);
if(-1 == ret)
{
perror("close");
return;
}
}
int main()
{
test01();
test02();
return 0;
}
stat 函数可以获取文件的信息。
int stat(const char *pathname, struct stat *statbuf);
头文件:
#include
#include
#include
pathname 指的是文件的路径。
statbuf (传入传出参数)保存获取的文件信息。
成功返回0,失败返回 -1,并且 errno 会被设置为合适的值,使用 perror 函数打印。
**manpage查看:**stat结构体在man 2 stat
中,st_mode中一些宏的查看在man 7 inode
struct stat 结构体:
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* Inode number */
mode_t st_mode; /* 文件的类型、文件的权限*/
nlink_t st_nlink; /* 文件的硬链接数 */
uid_t st_uid; /* 文件所有者ID */
gid_t st_gid; /* 文件所有者组ID */
dev_t st_rdev; /* Device ID (if special file) */
off_t st_size; /* 文件大小*/
blksize_t st_blksize; /* Block size for filesystem I/O */
blkcnt_t st_blocks; /* Number of 512B blocks allocated */
struct timespec st_atim; /* Time of last access */
struct timespec st_mtim; /* Time of last modification */
struct timespec st_ctim; /* Time of last status change */
};
示例代码:
#include
#include
#include
#include
#include
void test01()
{
struct stat info;
int ret = stat("demo01.txt",&info);
if(-1 == ret)
{
perror("stat");
return;
}
printf("文件大小为:%ld\n",info.st_size);
if(S_ISREG(info.st_mode))
{
printf("普通文件\n");
}
if(S_ISDIR(info.st_mode))
{
printf("目录文件\n");
}
if(S_ISLNK(info.st_mode))
{
printf("硬链接\n");
}
if(info.st_mode & S_IRUSR)
{
printf("用户的读权限\n");
}
if(info.st_mode & S_IWUSR)
{
printf("用户的写权限\n");
}
if(info.st_mode & S_IXUSR)
{
printf("用户的执行权限\n");
}
if(info.st_mode & S_IRGRP)
{
printf("用户组的读权限\n");
}
if(info.st_mode & S_IWGRP)
{
printf("用户组的写权限\n");
}
if(info.st_mode & S_IXGRP)
{
printf("用户组的执行权限\n");
}
if(info.st_mode & S_IROTH)
{
printf("其他用户的读权限\n");
}
if(info.st_mode & S_IWOTH)
{
printf("其他用户的写权限\n");
}
if(info.st_mode & S_IXOTH)
{
printf("其他用户的执行权限\n");
}
}
int main()
{
test01();
return 0;
}
使用 truncate 函数可将指定文件扩展为指定大小。
int truncate(const char *path, off_t length);
int ftruncate(int fd, off_t length);
注意:off_t 是 long 类型
头文件:#include
#include
#include
#include
#include
#include
void test()
{
int fd = open("download.txt",O_WRONLY | O_CREAT);
if(-1 == fd)
{
perror("open");
return;
}
int ret = ftruncate(fd,1024);
if(-1 == ret)
{
perror("ftruncate");
return;
}
ret = close(fd);
if(-1 == ret)
{
perror("close");
return;
}
}
int main()
{
test();
return 0;
}