4.2 fputc的使用
这里写自定义目录标题
fputc的定义:
![](https://i-blog.csdnimg.cn/blog_migrate/dbf4daca409e3e618c26f9a82a8e0565.png#pic_center)
主要功能:一个字符一个字符的写进文件,将int类型的字符character写进文件流(FILE* stream)中,返回一个整形。如果成功fputc会返回写进文件的字符,如果发生错误,fputc会返回EOF(-1)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/31d0d4ae5d6ded93b981e38dac863178.png#pic_center)
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/af176b5b0acd4d884f1a3d28f0d47aab.png#pic_center)
代码1:
int main()
//{
// //打开文件
// FILE* pf = fopen("test.txt", "w");
// if (pf == NULL)
// {
// perror("fopen");
// return 1;
// }
// //成功打开文件并开始写文件
// fputc('a', pf);//把字符a写进文件
// fputc('b', pf);
//
// //关闭文件
// fclose(pf);
// pf = NULL;
//
// return 0;
//}
代码2:
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//成功打开文件并开始写文件
//将26个英语字母写进文件
char ch = 0;
for (ch = 'a'; ch <= 'z'; ch++)
{
fputc(ch, pf);
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
解析:能够使用for循环一次性输出26个英语字母,这是因为fputc没有遇到错误就会一直向文件写。
4.3 fgets的使用
需要注意的是:fgets会在读取字符串时主动在文件末尾加上‘\0’,既如果我们要读取n个字符,那我们只能读取(n - 1)个字符。
代码3:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[10] = { 0 };
fgets(arr, 10, pf);
fclose(pf);
pf = NULL;
return 0;
}
test.txt中的内容:
hello world
运行结果:
解析:我们可以看到数组第十个数arr[9]为’\0’,但是我们知道test.txt文件流中第10个元数为l,所以我们需要注意fgets的使用会在文件末尾主动加上‘\0’。
验证代码:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
char arr[20] = "xxxxxxxxxxxxxxxxxxx";
fgets(arr, 20, pf);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
解析:
我们首先将数组开辟20个字节大小并全部初始化为x,当在test.txt文件流中的字符串“hello world”读取时,我们将数组前11个元素赋值为“hello world”。但是我们可以看到在第11个元素的位置有‘\0’,并且后面的元素仍为x。这间接说明fgets会主动在读取完字符串后主动加上’\0’。
4.4 fputs的使用
主要功能:
将被指针指向的字符串写进文件流(FILE*stream)中,直到遇到 ‘\0’ ,不会将‘\0’写进文件流。
代码4:
int main()
{
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fputs("hello world", pf);
fclose(pf);
pf = NULL;
return 0;
}
运行结果:成功将字符串“hello world”写进文件“test.txt”
4.5 fseek 的使用
主要功能:根据文件指针的位置和偏移量确定文件指针指向的内容
其中(FILE*stream)指的是要查找的文件流,在代码5中指的是文件流pf,(long int offset)指的是相对于当前鼠标的偏移量,(int origin)指的是指针当前的位置。其中指针当前的位置共有3个,分别是文件的起始位置(SEEK_SET),文件指针的当前位置(SEEK_CUR),和文件末尾(SEEK_END)。
代码5://SEEK_CUR的使用
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = fgetc(pf);
printf("%c\n", ch);//a
fseek(pf, 4, SEEK_CUR);
ch = fgetc(pf);
printf("%c\n", ch);//f
fclose(pf);
pf = NULL;
return 0;
}
test.txt文件中的内容:
abcdefhhijk
运行结果:
解析:我们先使用fgetc从test.txt中读取一个字符a,此时光标在a后面闪烁,fseek(pf, 4, SEEK_CUR);的意思是从光标当前位置(即a的后面)向后查找偏移4个字节大小的字符(即f)。
代码6:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
int ch = fgetc(pf);
printf("%c\n", ch);//a
fseek(pf, 4, SEEK_SET);
ch = fgetc(pf);
printf("%c\n", ch);//f
fclose(pf);
pf = NULL;
return 0;
}
运行结果:
解析:
我们先使用fgetc从test.txt中读取一个字符a,此时光标在a后面闪烁,fseek(pf, 4, SEEK_SET);的意思是从文件起始位置(即a的前面)向后查找偏移4个字节大小的字符(即e)。要注意的是即便我们一开始已经读取了1个字节内容并且光标位置发生改变但是这并不影响偏移量的开始位置(文件的起始位置),即无论在我们调用fseek(pf, 4, SEEK_SET);时前面已经使用过多少次fgetc,这都不会改变我们的读取结果为e。
代码7:
int main()
{
FILE* pf = fopen("test.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
fclose(pf);
pf = NULL;
return 0;
}
test.txt的代码:
abcdefghijk
运行结果:
解析:
我们先使用fgetc从test.txt中读取一个字符a,此时光标在a后面闪烁,fseek(pf, -4, SEEK_END);的意思是从文件末尾位置(即k的后面)向前查找偏移4个字节大小的字符(即h)。要注意的是即便我们一开始已经读取了1个字节内容并且光标位置发生改变但是这并不影响偏移量的开始位置(文件的末尾位置),即无论在我们调用fseek(pf, -4, SEEK_END);时前面已经使用过多少次fgetc,这都不会改变我们的读取结果为h。
这里的偏移量之所以是-4是因为SEEK_END是从最末尾开始读取字节。所以我们需要向前读取字符内容,向后读取4个字节为4,读取-4个字节就相当于向前读取4个字节。