一.文件的打开与关闭
- 为了读写文件,我们需要用到定义在stdio.h这个标准库头文件中的一些函数结构
-
下面按顺序列出我们打开一个文件,进行读写操作所必须遵循的一个流程
1.调用“文件打开”函数fopen,返回一个指向该文件的指针
2.检测文件是否打开成功,通过第一步fopen的返回值(文件指针)来判断,如果指针为NULL,则表示打开失败,我们需要停止操作,并且返回一个错误
3.如果文件打开成功,就可以用stdio.h中的读写函数来读写文件
4.完成读写操作,关闭文件,调用“文件关闭”函数fclose
1.fopen:打开文件
//函数原型
FILE* fopen(const char* fileName,const char* openMode);
- fileName:文件名,字符串类型,不可变
- openMode:打开方式,表明我们打开文件之后要干什么
可用的openMode
- 函数返回值:FILE指针
2.fclose:关闭文件
//函数原型
int fclose(FILE* pointerOnFile);
- pointerOnFile:指向文件文件的指针
-
函数的返回值(int)有两种情况:
1.0:当关闭操作成功时
2.EOF(一般是-1):如果关闭失败 - 关闭这个文件,目的是为了释放占用的文件指针
二.读写文件的不同方法
学习如何对文件进行读出和写入
1.对文件写入
我们学习三个写入的函数
- fputc:file put character,在文件中写入一个字符
- fputs:file put string,在文件中写入一个字符串
- fprint:在文件中写入一个格式化过的字符串,用法与printf几乎相同,只是多了一个文件指针
fputc
int fputc(int character, FILE*pointerOnFile);
- character:int型变量,表示要写入的字符
- pointerOnFile:指向文件的指针
- 函数返回值int:如果写入失败,则为EOF,否则会是另一个值
示例:
//程序用于向test.txt写入字符'A'
#include <stdio.h>
int main(int argc, const char* argv[]) {
FILE* file = NULL;
file = fopen("/Users/xulei/Desktop/test.txt", "w");
if (file == NULL) {
printf("error");
}
fputc('A', file);
fclose(file);
return 0;
}
运行之后,会在我所给的路径(桌面)下,创建一个test.txt
test.txt
fputs
int fputs(const char* string, FILE* pointerOnFile);
- stringr:char型变量,表示要写入的字符串
- pointerOnFile:指向文件的指针
- 函数返回值int:如果写入失败,则为EOF,否则会是另一个值
示例:
//程序用于向test.txt写入字符串
#include <stdio.h>
int main(int argc, const char* argv[]) {
FILE* file = NULL;
file = fopen("/Users/xulei/Desktop/test1.txt", "w");
if (file == NULL) {
printf("error");
}
fputs("你好,朋友\n最近怎么样", file);
fclose(file);
return 0;
}
运行之后,会在我所给的路径(桌面)下,创建一个test1.txt
test1.txt
fprintf
int fprintf(FILE* stream, const char *format, ...);
不仅可以向文件写入字符串,而且这个字符串可以有由我们来格式化
示例:
//程序用于向test.txt写入字符串
#include <stdio.h>
int main(int argc, const char* argv[]) {
FILE* file = NULL;
int age = 0;
file = fopen("/Users/xulei/Desktop/test2.txt", "w");
if (file == NULL) {
printf("error");
}
printf("你几岁了?\n");
scanf("%d",&age);
fprintf(file, "使用者年龄是%d岁\n",age);
fclose(file);
return 0;
}
//运行结果
你几岁了?
2
Program ended with exit code: 0
运行之后,会在我所给的路径(桌面)下,创建一个test2.txt
test2.txt
2.对文件读出
我们学习三个读出的函数
- fgetc:file get character,在文件中读出一个字符
- fgets:file get string,在文件中读出一个字符串
- fscanf:在文件中读出一个格式化过的字符串,用法与scanf几乎相同,scanf是从用户输入读取,而fscanf是从文件读取
fgetc
int fgetc(FILE*pointerOnFile);
- pointerOnFile:指向文件的指针
- 函数返回值int:函数返回值是读到的字符,如果不能读到字符,那会返回EOF
-
fgetc函数每读入一个字符,这个虚拟的游标就移动这个一个字符长度,我们就可以用一个循环读出所有的字符
示例:
#include <stdio.h>
int main(int argc, const char * argv[]) {
FILE* file = NULL;
int currentCharacter = 0;
file = fopen("/Users/xulei/Desktop/test2.txt", "r");
if (file == NULL) {
printf("error");
}
do {
currentCharacter = fgetc(file);//读取一个字符
printf("%c",currentCharacter);//显示读取的字符
} while (currentCharacter != EOF);
printf("\n");
fclose(file);
return 0;
}
//运行结果
使用者年龄是2岁
\377
Program ended with exit code: 0
//\377,其实就是-1,也就是EOF,表示读到末尾
/*
\是C语言的转义字符的起始标识。
当\后面直接接数字的时候,会被处理成对应的8进制。
于是\377也就是8进制377对应的ascii码值,将其转为二进制为
3 = 11
7 =111
于是值为11 111 111
也就是16进制的0xff, 10进制值为255。
这个是单字节无符号数所能表示的最大值,作为有符号数时,值为-1
*/
fgets
char *fgets(char *string, int characterNumberToRead, FILE* pointerOnFile);
这个函数每次最多读一行,因为它遇到第一个'\n'(换行符)会结束读取
示例:
#include <stdio.h>
int main(int argc, const char * argv[]) {
FILE* file = NULL;
char string[1000] = " ";//保证数组足够大
file = fopen("/Users/xulei/Desktop/test1.txt", "r");
if (file == NULL) {
printf("error");
}
while (fgets(string, 1000, file) != NULL) {//只要某一行不是空值就读取它
printf("%s\n",string);
}
fclose(file);
return 0;
}
//运行结果
你好,朋友
最近怎么样
Program ended with exit code: 0
fscanf
int fscanf(FILE* stream, const char *format, ...);
此函数原理和scanf是一样的,负责从文件中读取规定样式的内容
示例:
#include <stdio.h>
int main(int argc, const char * argv[]) {
FILE* file = NULL;
int score[3] = {30,19,32,};
//文件写入
file = fopen("/Users/xulei/Desktop/test3.txt", "w");
if (file == NULL) {
printf("error");
}
for (int i = 0; i < 3; i++) {
fputc(i, file);
}
fclose(file);
//文件读取
file = fopen("/Users/xulei/Desktop/test3.txt", "r");
if (file == NULL) {
printf("error");
}
fscanf(file, "%d %d %d",&score[0],&score[1],&score[2]);
printf("%d %d %d",score[0],score[1],score[2]);
printf("\n");
fclose(file);
return 0;
}
//运行结果
30 19 32
Program ended with exit code: 0
三.在文件中移动
前面我们提到一个虚拟的游标,现在我们仔细学一下
每当我们打开一个文件时,实际上都存在一个游标,标识你当前在文件中所处的位置,可以类比我们编辑文本时的光标
三个与文件中游标移动有关的函数:
- ftell:告诉目前在文件中那个位置
- fseek:移动文件中的游标到指定位置
- rewind:将游标重置到文件的开始位置
ftell
返回一个long型的整数值,表明目前游标所在位置
long ftell(FILE* pointerOnFile);
fseek
此函数能使游标在文件(pointerOnFile指针所指)中从位置(origin所指)开始移动一段距离(move所指)
int fseek(FILE* pointerOnFile, long move, int origin);
- move:可以是一个正整数,表明向前移动;0,不移动;负整数,表明回退
-
origin:它有三个取值
1.SEEK_SET:文件开始处
2.SEEK_CUR:游标当前所处位置
3.SEEK_END:文件末尾
例子:
fseek(file, 5, SEEK_SET);
//这行代码将游标放置到距离文件开始处5个位置的地方。
fseek(file, -3, SEEK_CUR);
//这行代码将游标放置到距离当前位置往后3个位置的地方
fseek(file, 0, SEEK_END);
//这行代码将游标放置到文件末尾。
rewind
相当于使用fseek来使游标回到0的位置
void remind(FILE* pointerOnFile);
//相当于fseek(file,0,SEEK_SET);
四.文件的重命名和删除
两个简单的函数:
- rename:重命名一个文件
- remove:删除一个文件
rename
int rename(const char *oldName, const char *newName);
如果函数执行成功,则返回0,否则返回非0的int型值
示例:
int main(int argc, char *argv[]){
rename("test.txt", "renamed_test.txt");
return 0;
}
remove
int remove(const char *fileToRemove);
fileToRemove就是我们要删除的文件名
示例:
int main(int argc, char *argv[]){
remove("test.txt");
return 0;
}
五.数据块读写函数fread 和 fwrite
读数据块数据的格式: fread(buffer,size,count,fp);
写数据块数据的格式: fwrite(buffer,size,count,fp);
-
buffer -- 是一个指针,在fread函数中,它表示存放输入数据的首地址。在fwrite函数中,它表示存放输出数据的首地址。
-
size -- 表示数据库的字节数
-
count -- 表示要读写的数据库块数
-
fp -- 表示文件指针
fread(fa,4,5,fp);
--> 意义: 是从fp所指的文件中,每次读4个字节(一个实数)送入实数组fa中,连续5次,即读5个实数到fa中
网友评论