前言
正文
一、为什么要使用文件
如果想要让自己编写的程序中的内容不丢失,下次还能使用,这就需要文件来保存它。
二、文件的打开与关闭操作
int main()
{
FILE* pf =fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fclose(pf);
pf = NULL;
return 0;
}
1.fopen
(1)r,w,a
1.r (只读):为了读数据而打开一个文件,当文件不存在时就会出错 2.w(只写):为了写数据到文件里(如果打开文件时文件里已有数据,则当输入数据时会将已有内容覆盖),当文件不存在时就自动创建一个文件 3.a (追加):向文件尾部追加数据,当文件不存在时自动创建一个文件
(2)r+,w+,a+
和r,w,a 差不多只不过r+,w+,a+功能不是r,w,a那么单一,他们都是为了读写操作而打开文件。
(3)rb,wb,ab
和r,w,a不同的是这里打开的文件是一个二进制文件
(4)rb+,wb+,ab+
这里也是对比上面的rb,wb,ab进行的是读写操作
2.fclose
三、文件的顺序读写函数
1.fgetc fputc
将一个字符向文件输出,也就是将字符写入文件中(不会自动换行。)
int main()
{
FILE* pf =fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fclose(pf);
pf = NULL;
return 0;
}
将文件里的字符输入到内存中,即从文件中读取字符到内存里
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int arr = fgetc(pf);
printf("%c", arr);
fclose(pf);
pf = NULL;
return 0;
}
2.fgets fputs
1.将str指向的字符串写入文件中 2.该函数从指定的地址 (str) 开始复制,直到达到终止空字符 (‘\0’)。此终止空字符不会复制到文件中。(不会自动换行。)
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputs("abcdefg", pf);
fclose(pf);
pf = NULL;
return 0;
}
1.从文件中获取字符串存储到str中,直到读取 (num-1) 个字符或到达换行符或文件结尾,以先发生者为准。 2.换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。 3.终止空字符会自动追加到复制到 str 的字符之后。 这里的1,3就是指当要获取的字符个数,小于这一行的字符数时。 如果当要获取的字符num大于这一行的字符数,那么也只会读取这一行的数据(即到结尾),不会往下获取数据。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = "";
fgets(arr,5, pf);
printf("%s", arr);
fclose(pf);
pf = NULL;
return 0;
}
3.fscanf fprintf
这两个函数是按参数的格式,输入/输出函数,在使用上只比scanf,printf多了一个参数。
struct people
{
char name[20] ;
int age;
char tele[20];
};
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct people s = { "zhangsan",18,"18273822"};
fprintf(pf, "%s %d %s", s.name, s.age, s.tele);
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct people s2 = { 0 };
fscanf(pf, "%s %d %s", s2.name, &(s2.age), &(s2.tele));
printf("%s %d %s", s2.name, s2.age, s2.tele);
fclose(pf);
pf = NULL;
return 0;
}
4.fread fwrite
1.这两个函数用于二进制文件的读写(上面已经介绍过了二进制文件打开方式了哟)。 2.第一个参数是一个指向内存块的指针。 3.第二个参数是要读取得每个元素的大小(以字节为单位)。 4。第三个参数是元素数。 5.第四个参数是自画像文件流的指针变量。
**
int main()
{
FILE* pf = fopen("test.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct people s = { "zhangsan",18,"18273822" };
fwrite(&s, sizeof(struct people), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
FILE* pf = fopen("test.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
struct people s1 = { 0 };
fread(&s1, sizeof(struct people), 1, pf);
printf("%s %d %s", s1.name, s1.age, s1.tele);
fclose(pf);
pf = NULL;
return 0;
}
四、文件的随机读写函数
上面介绍的是文件的顺序读写 1.我们以r的形式打开文件是因为要读取数据,指针在开头。 2.以w/a的形式代开文件是因为要写入/追加数据,指针在上一个数据的末尾。 3.那如果我们想在文件的中间读取或者写入数据怎么办呢?这个时候就要用到以下的几个函数来调整文件中指针所在的位置
1.fseek
参数一指针的起始位置有 以下几种
1.第二个参数是据起始位置的偏移量。 通过改变偏移量来改变指针的位置,以此达到获取想要的数据的效果。
现在文件指针指向的的是文件起始位置,我拿一个字符拿到的是’a’,但是如果我将指针向后偏移一个位置,那此时我拿到的就应该是’b’。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 1, SEEK_CUR);
int arr = fgetc(pf);
printf("%c", arr);
fclose(pf);
pf = NULL;
return 0;
}
2.ftell
这个函数是用于告诉我们指针相对于起始位置的偏移量 如上段代码所示,我们读到了’b’后,指针自动向后跳了一步,此时的偏移量应该是2。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 1, SEEK_CUR);
int arr = fgetc(pf);
printf("%c\n", arr);
int tem = ftell(pf);
printf("%d", tem);
fclose(pf);
pf = NULL;
return 0;
}
3.rewind
这个函数的作用是将文件的指针调整,让它回到去指向文件的首部。 我们接着上面的代码,使用该函数后再获取一个字符,这个字符应该是’a’。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 1, SEEK_CUR);
int arr = fgetc(pf);
printf("%c\n", arr);
int tem = ftell(pf);
printf("%d\n", tem);
rewind(pf);
int arr2 = fgetc(pf);
printf("%c", arr2);
fclose(pf);
pf = NULL;
return 0;
}
五、文件读取结束的判定
1.feof
这个函数是用来判断的当前文件读取结束的原因的。 如果设置了文件结束标识符,这个函数的返回值为非0数,否则返回0(遇到错误导致暂停)。
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = "";
fgets(arr,sizeof(arr), pf);
printf("%s\n", arr);
int m = 0;
if (m = feof(pf))
{
printf("END by EOF\n");
}
else
{
printf("END by IO Error\n");
}
fclose(pf);
pf = NULL;
return 0;
}
六、文本文件与二进制文件
文本文件时基于字符编码的文件,我们最常见的编码就是ASCII码。(上述打开文件时文件的后缀是“txt”这就是以文本文件)。 二进制文件时基于值编码的文件。 对于二进制文件我们以10000来做个介绍。
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen:");
return 1;
}
int a = 10000;
fwrite(&a, sizeof(a), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
|