这里博主接上文C语言-文件操作(1)-CSDN博客,让我们再次来探讨一下C语言中文件操作的相关内容吧!
2.4 fwrite的用法
fwrite作为二进制的输出,适用于文件输入流。
在Everything中,
//fwrite怎么用?
fwrite(const void * ptr,size_t size,size_t count,FILE * stream);
//ptr是指指定的数组,size_t size可以理解为数组中的内容,比如说指向的数字的字节数,size_t count可以理解为指向的数组中有几个元素,FILE*stream,为流
//fread怎么用?
fread(void* ptr,size_t size,size_t count,FILE* stream);
//类似于fwite,这里可以进行类比
这里我们就来用一下这个fwrite.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void)
{
int arr[] = { 1,2,3,4,5,6 };
FILE* pf = fopen("text.txt", "wb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件,二进制文件
int sz = sizeof(arr) / sizeof(arr[0]);
fwrite(arr, sizeof(arr[0]), sz, pf);
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
相应的来学习fread.
#include<stdio.h>
int main(void)
{
int arr[5] = { 0 };
FILE* pf = fopen("text.txt", "rb");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件,二进制文件
//读五个二进制数据
fread(arr, sizeof(arr[0]), 5, pf);
int i=0;
for(i=0;i<5;i++)
{
printf("%d ",arr[i]);//1 2 3 4 5
}
//也可以这样读文件
//int i=0;
//while(fread(arr+i,sizeof(int),1,pf))
//{
// printf("%d ",arr[i]);
// i++;
//}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
3.文件的随机读写
3.1.fseek的用法
有三种位置:
SEEK_SET :用在文件起始位置
SEEK_CUR:用在文件指针当前位置
SEEK_END:用在文件末尾
这里来解释一下三种用法:
#include<stdio.h>
int main(void)
{
FILE* pf = fopen("text.txt", "r");//只读文件
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ch = fgetc(pf);
printf("%c\n", ch);//这里会打印出a,因为text.txt的文件中存放的是abcdefghi
fseek(pf, 4, SEEK_CUR);//指针指在a的位置,因为是起始位置
fseek(pf, 5, SEEK_SET);//从开始位置向后数5个字母,恰好到f
fseek(pf, 4, SEEK_END);//从位置倒数4个字符,是f
ch = fgetc(pf);
printf("%c\n", ch);//f
fclose(pf);
pf = NULL;
return 0;
}
针对代码进行详细的解释。
3.2. ftell的用法
用于返回文件指针相对于起始位置的偏移量。
#include<stdio.h>
int main(void)
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ch = fgetc(pf);
printf("%c\n", ch);//a,首先指向a
fseek(pf, 0, SEEK_END);//SEEK-END从光标最后开始指
printf("%d\n", ftell(pf));
fclose(pf);
pf = NULL;
return 0;
}
3.3 rewind的用法
让文件指针的位置回到文件的起始位置。
//rewind的用法
int main(void)
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读文件
int ch = fgetc(pf);
printf("%c\n", ch);//a
fseek(pf, -4, SEEK_END);
ch = fgetc(pf);
printf("%c\n", ch);//f
rewind(pf);
ch = fgetc(pf);
printf("%c\n", ch);//a
fclose(pf);
pf = NULL;
return 0;
}
4.文件读取结束的判定
4.1 被错误使用的feof
feof的作用是:当文件读取结束的时候,判断读取结束的原因是否是:遇到文件尾结束。
假如说文件现在读取结束了,有可能遇到了两个问题:
1.可能是文件读取过程中发生了错误:perror
2.有可能是文件读取结束了:feof
当我们在打开一个流的过程中,这个流上有2个标记值:1.是否遇到文件末尾;2.是否读取过程中发生错误。
fgetc---如果读取正常,返回的是读取到的字符的ASCII码值
如果读取的过程中遇到文件末尾,或者发生错误,就返回EOF
fgets---如果读取正常,返回的是存储到的字符串的字符数组的地址
如果读取的过程中遇到文件末尾,或者发生错误,就返回NULL
#include<stdio.h>
int main(void)
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//读取
int ch = 0;
while ((ch = fgetc(pf)) != EOF)
{
printf("%c\n", ch);
}
//判读是什么原因导致读取结束的
if (feof(pf))
{
printf("遇到文件末尾,读取正常结束\n");
}
else if (ferror(pf))
{
perror("fgetc");//读取过程中发生了错误
}
return 0;
}
#include<stdio.h>
int main(void)
{
FILE* pf = fopen("text.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写
char ch = 0;
for (ch = 'a'; ch <= 'z'; ch++)
{
fputc(ch, pf);//这里是文件写入,循环打印出从a到z的字母
}
//判断是什么原因导致其读取结束的
if (feof(pf))
{
printf("遇到文件末尾,读取正常结束\n");
}
else if (ferror(pf))
{
perror("fputc");
}
return 0;
}
4.2 文件拷贝
用pfin,这里我们话不多说,直接开始上代码
int main(void)
{
FILE* pfin = fopen("text1.txt", "r");//用只读方式打开
if (pfin == NULL)
{
perror("fopen:text1.txt");
return 1;
}
FILE* pfout = fopen("text2.txt", "w");//把text1.txt的内容拷贝到text2.txt
if (pfout == NULL)
{
fclose(pfin);
perror("fopen:text2.txt");
return 1;
}
//读文件和写文件
int ch = 0;
while ((ch = fgetc(pfin)) != EOF)
{
fputc(ch, pfout);
}
//关闭文件
fclose(pfin);
pfin=NULL;
fclose(pfout);
pfout=NULL;
return 0;
}
5.文件缓冲区
ANSIC标准采用“缓冲文件系统”处理数据文件,缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。
从内存向磁盘输出数据会先送到内存中的缓冲区中,装满缓冲区后才一起送到磁盘上,如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。
缓冲区的大小根据C编译系统决定。