文件
概述
描述
文件用来存放程序、文档、音频、视频数据、图片等数据的。
文件就是存放在磁盘上的,一些数据的集合。
分类
磁盘文件
如
word,pdf,txt,
编写的
.c
文件
,
编译的
.o
文件
,
压缩包等
二进制文件
如
:
音频
,
视频
,
图片
基于值编码
,
需要特定程序打开
文本文件
如
:txt
文件
基于字符编码,常见编码有
ASCII
、
UNICODE
等
一般可以使用文本编辑器直接打开
设备文件
接入电脑的外设
,
如屏幕
,
键盘
,
鼠标
,U
盘等
注意
:
键盘:标准输入文件 屏幕:标准输出文件
缓冲区
文件缓冲区是库函数申请的一段内存,由库函数对其进行操作,程序员没有必要知道存
放在哪里
.
优点
:
提高其读写效率
缓冲区到文件或程序的情况
行缓冲
有换行就缓冲
#include
int main(int argc, char const *argv[])
{
printf("
德玛西亚
\n");
while(1);
return 0;
}
满缓冲
当缓冲区中的内容满了后
,
将冲刷
强制缓冲
手动调用
fflush
函数
fflush(
文件指针
);
stdio
提供的文件指针
stdout:
标准输出
stdin:
标准输入
stderr:
错误输出
#include
int main(int argc, char const *argv[])
{
printf("
德玛西亚
");
fflush(stdout);//
强制缓冲
,stdout:
标准输出
,stdin:
标准输入
,stdio.h
提供的
while(1);
return 0;
}
关闭缓冲
#include
int main(int argc, char const *argv[])
{
printf("
德玛西亚
");
return 0;
}
无缓冲
没有缓冲区
在读写文件的时候通过系统调用
io
(
read write
)
,
对文件进行读写数据
这个时候是无缓冲的,即写数据会立马进入文件,读数据会立马进入内存
文件指针
概述
存储文件地址的指针变量
文件指针在程序中用来标示(代表)一个文件的,在打开文件的时候得到文件指针
操作步骤
1,
打开文件获取文件指针
2,
操作文件指针
读
写
3,
关闭文件
FILE
结构体在
stdio
中定义的
,
如下
typedef struct
{
short level; //
缓冲区
“
满
”
或
“
空
”
的程度
unsigned flags; //
文件状态标志
char fd; //
文件描述符
unsigned charhold; //
如无缓冲区不读取字符
short bsize; //
缓冲区的大小
unsigned char *buffer; //
数据缓冲区的位置
unsigned ar*curp; //
指针,当前的指向
unsigned istemp; //
临时文件,指示器
shorttoken; //
用于有效性检查
}
FILE
;
相关函数
fopen打开文件
语法
FILE *fopen(const char *path, const char *mode)
参数
:
path:
要打开的文件地址
注意
:
可以是相对路径也可以是绝对路径
mode:
r:
只读
w:
只写
,
如果文件存在
,
清空原文件中的内容
,
在写入
,
如果文件不存在
,
新建文
件
,
在写入
a:
追加
,
如果文件存在
,
在原文件内容尾部写入
,
如果文件不存在
,
新建文件
,
在
写入
rb:
二进制读取
wb:
二进制写入
ab:
二进制追加
r+:
可读可写
,
不会创建新文件
w+:
可读可写
,
会创建新文件
a+:
可读可写追加
rb+
wb+
ab+
返回值
:
打开的文件对应的文件指针
如果为
NULL,
打开失败
fclose
关闭文件
语法
int fclose(FILE *fp);
参数
:
fp:
要关闭的文件指针
返回值
:
为
0
成功
,
非
0
失败
fflush
冲刷缓冲区
语法
int fflush(FILE *stream);
参数
:
stream:
要冲刷的文件指针
fgetc
与
fputc
fgetc
作用
:
从文件中一次读取一个字节
语法
:
int fgetc(FILE *stream);
参数
:
stream:
要读取的文件指针
返回值
:
读取到的字符
读取结束或失败
文本文件返回
EOF
EOF
由
stdio.h
文件提供的一个符号常量
,
值是
-1
二进制文件返回
feof(
后面会讲
)
fputc
作用
:
一次给文件中写入一个字节
语法
:
int fputc(int c, FILE *stream)
参数
:
c:
写入的字符
stream:
写入的文件对应的指针
返回值:
如果输出成功,则返回输出的字节值;
如果输出失败,则返回一个
EOF
。
fgets
与
fputs
fgets
函数头
:
stdio.h
函数
:
char *fgets(char* s,int size,FILE *stream);
参数
:
s:
存储读取到的字符串的变量
size:
这是要读取的最大字符数
(
包括最后的空字符
)
。通常是使用以
str
传递的数
组长度。
stream:
读取的文件指针
返回值
:
成功返回读取的字符
失败返回
NULL
注意
:
读取到换行或文件结束
fputs
函数头
:
stdio.h
函数
:
int fputs(const char *s, FILE *stream);
参数
:
s:
写入的字符串
stream:
写入的文件指针
返回值
:
成功返回写入的字节数
失败返回
-1
fread
与
fwrite
fread
作用
:
一次读一块
,
主要用于文件传输
函数
函数头
stdio.h
函数
size_t fwrite(viod *ptr,size_t size,size_t nmemb,FILE *stream)
参数
:
ptr:
指向带有最小尺寸的
size*nmemb
字节的内存块的指针
size:
读取的每个元素的大小
,
单位字节
nmemb:
读取的元素个数
stream:
读取的文件指针
返回值
:
实际读到的块数。
fwrite
作用
:
一次写一块
,
主要用于文件传输
函数
函数头
stdio.h
函数
size_t fwrite(void *ptr, size_t size, size_t nmemb, FILE *stream);
参数
:
ptr:
这是指向要被写入的元素数组的指针。
size:
这是要被写入的每个元素的大小,以字节为单位。
nmemb:
这是元素的个数,每个元素的大小为
size
字节。
stream:
这是指向
FILE
对象的指针,该
FILE
对象指定了一个输出流。
返回值
:
实际写入的块数
示例
#include
struct
STU
{
char
name
[
20
];
int
age
;
char
sex
[
10
];
};
void
write
(){
FILE
*
stuF
=
fopen
(
"stuinfo"
,
"w"
);
if
(
stuF
==
NULL
)
{
printf
(
"
文件不存在
"
);
return
;
}
struct
STU stus
[
3
];
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
printf
(
"
请输入第
%d
个学员信息
,
格式为
:
姓名 年龄 性别
\n"
,
i
+
1
);
//
数组名存储的就是数组第一个元素的地址
,
本身就是一个指针
scanf
(
"%s %d %s"
,
stus
[
i
].
name
,
&
stus
[
i
].
age
,
stus
[
i
].
sex
);
}
int
num
=
fwrite
(
stus
,
sizeof
(
struct
STU
),
3
,
stuF
);
fclose
(
stuF
);
printf
(
"OVER,num:%d\n"
,
num
);
}
//
全局变量数组中的数据默认为
0
struct
STU stus
[
10
];
void
read
()
{
FILE
*
f
=
fopen
(
"stuinfo.txt"
,
"r"
);
fread
(
stus
,
sizeof
(
struct
STU
),
10
,
f
);
fclose
(
f
);
for
(
int
i
=
0
;
i
<
10
;
i
++
)
{
printf
(
"%s %d %s\n"
,
stus
[
i
].
name
,
stus
[
i
].
age
,
stus
[
i
].
sex
);
}
}
int
main
(
int
argc
,
char
const
*
argv
[])
{
read
();
return
0
;
}
fscanf
与
fprintf
fscanf
作用
:
从文件中格式化读取
函数
函数头
:
stdio.h
函数
:
int fscanf(FILE *stream, const char *format, ...)
参数
:
stream:
文件指针
format:
格式化字符串
...:
输入数据列表
返回值
:
成功
:
该函数返回成功匹配和赋值的个数。如果到达文件末尾或发生读错误
,
则返回
EOF
fprintf
作用
:
给文件中格式化写入
函数
函数头
:
stdio.h
函数
int fprintf(FILE *stream, const char *format, ...)
参数
:
stream:
文件指针
format:
格式化字符串
...:
输出数据列表
返回值
:
成功
:
则返回写入的字符总数
,
失败
:
返回一个负数。
补充:
以上读写称为顺序读写
,
文件读写的位置在上一次之后
以下读写称为随机读写
,
文件读写的位置可以发生改变
rewind
复位
作用
:
设定文件位置为文件开头
函数
函数头
stdio.h
函数
void rewind(FILE *stream)
参数
指针文件
示例:
#include
int
main
(
int
argc
,
char
const
*
argv
[])
{
FILE
*
f
=
fopen
(
"a.txt"
,
"r"
);
char
str
[
50
];
fgets
(
str
,
sizeof
(
str
),
f
);
printf
(
"%s"
,
str
);
rewind
(
f
);
fgets
(
str
,
sizeof
(
str
),
f
);
printf
(
"%s"
,
str
);
return
0
;
}
fseek
定位
作用
:
设置文件指针位置
函数
函数头
:
stdio.h
函数
:
int fseek(FILE *stream, long int offset, int whence)
参数
:
stream:
文件指针
offset:
相对于
whence
的偏移量
whence:
位置
,0,
开始
,1,
当前位置
,2,
结尾
ftell
作用
:
获取指针偏移量
,
测量文件读写位置距文件开始有多少字节
函数
函数头
:
stdio.h
函数
:
long int ftell(FILE *stream)
参数
:
文件指针
返回值
:
文件读写位置距文件开始的字节数
makefile
问题
当编译程序时所需的源文件或连接的库文件过渡
,
导致编译命令过长
每次书写困难
为了简化其操作系统提供了
gnu make
检查
GNU make
是否存在
which make
make --version
make
与
makefile
EXEC =
main
OBJ =
main.o utils.o
FLAGS =
-Wall -g
CC =
gcc
$(EXEC)
:
$(OBJ)
$(CC) $(OBJ)
-o
$(EXEC) $(-Wall -g)
main.o:
main.c
$(CC)
-c main.c -o main.o
utils.o:
utils.c
$(CC)
-c utils.c -o utils.o
clear:
rm
$(EXEC)
*.o