C语言 文件操作相关函数
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 文件操作相关函数相关的知识,希望对你有一定的参考价值。
文章目录
头文件:stdio.h
#include <stdio.h>
文件打开关闭函数
文件打开(fopen)
文件的打开操作表示将给用户指定的文件在内存分配一个FILE结构区
,并将该结构的指针返回给用户程序,以后用户程序就可用此FILE指针
来实现对指定文件的存取操作了。当使用打开函数时,必须给出文件名、文件操作方式(读、写或读写)。
FILE * fopen(const char * filename, const char * mode);
- 功能:打开文件
- 参数:
filename
:需要打开的文件名,根据需要加上路径
mode
:打开文件的权限设置 - 返回值:
成功:文件指针
失败:NULL
参数mode可选值
方式 | 含义 |
---|---|
“r” | 打开,只读,文件必须已经存在。 |
“w” | 只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节。再重新写,也就是替换掉原来的文件内容文件指针指到头。 |
“a” | 只能在文件末尾追加数据,如果文件不存在则创建 |
“rb” | 打开一个二进制文件,只读 |
“wb” | 打开一个二进制文件,只写 |
“ab" | 打开一个二进制文件,追加 |
“r+” | 允许读和写,文件必须已存在 |
“w+” | 允许读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写 。 |
“a+” | 允许读和追加数据,如果文件不存在则创建 |
“rb+” | 以读/写方式打开一个二进制文件 |
“wb+” | 以读/写方式建立一个新的二进制文件 |
“ab+” | 以读/写方式打开一个二进制文件进行追加 |
案例
检查fopen的返回值:
如何函数失败,它会返回一个NULL值。如果程序不检查错误,这个NULL指针就会传给后续的I/O函数。它们将对这个指针执行间接访问,并将失败
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
FILE *fp = NULL;
// "\\\\"这样的路径形式,只能在windows使用
// "/"这样的路径形式,windows和linux平台下都可用,建议使用这种
// 路径可以是相对路径,也可是绝对路径
fp = fopen("../test", "w");
//fp = fopen("..\\\\test", "w");
if (fp == NULL) //返回空,说明打开失败
{
//perror()是标准出错打印函数,能打印调用库函数出错原因
perror("open");
return;
}
}
int main()
{
test();
return 0;
}
文件关闭(fclose)
文件操作完成后,如果程序没有结束,必须要用fclose()函数
进行关闭,这是因为对打开的文件进行写入时,若文件缓冲区的空间未被写入的内容填满,这些内容不会写到打开的文件中。只有对打开的文件进行关闭操作时,停留在文件缓冲区的内容才能写到该文件中去,从而使文件完整。再者一旦关闭了文件,该文件对应的FILE结构
将被释放,从而使关闭的文件得到保护,因为这时对该文件的存取操作将不会进行。文件的关闭也意味着释放了该文件的缓冲区。
int fclose(FILE * stream);
- 功能:关闭先前
fopen()
打开的文件。此动作让缓冲区的数据写入文件中,并释放系统所提供的文件资源。 - 参数:
stream
:文件指针 - 返回值:
成功:0
失败:-1
它表示该函数将关闭FILE指针对应的文件,并返回一个整数值。若成功地关闭了文件,则返回一个0值,否则返回一个非0值.
文件读写相关函数
总览
文件读写相关基本函数包括以下几个方面:
- 按照字符读写文件:fgetc(), fputc()
- 按照行读写文件:fputs(), fgets()
- 按照块读写文件:fread(), fwirte()
- 按照格式化读写文件:fprintf(), fscanf()
- 按照随机位置读写文件:fseek(), ftell(), rewind()
字符读写函数
int fputc(int ch, FILE * stream);
- 功能:将
ch
转换为unsigned char
后写入stream指定的文件中 - 参数:
ch
:需要写入文件的字符
stream
:文件指针 - 返回值:
成功:成功写入文件的字符
失败:返回-1
int fgetc(FILE * stream);
- 功能:从stream指定的文件中读取一个字符
- 参数:
stream
:文件指针 - 返回值:
成功:返回读取到的字符
失败:-1
int feof(FILE * stream);
- 功能:检测是否读取到了文件结尾
- 参数:
stream
:文件指针 - 返回值:
非0值:已经到文件结尾
0:没有到文件结尾
字符读写案例
将把流指针fp指向的文件中的一个字符读出,并赋给ch,当执行fgetc()函数
时,若当时文件指针指到文件尾,即遇到文件结束标志EOF(其对应值为-1)
,该函数返回一个 -1 给ch,在程序中常用检查该函数返回值是否为 -1 来判断是否已读到文件尾,从而决定是否继续。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//写文件
FILE* fp_write = NULL;
//写方式打开文件
fp_write = fopen("./mydata.txt", "w+");
if (fp_write == NULL) {
return;
}
char buf[] = "this is a test for pfutc!";
for (int i = 0; i < strlen(buf); i++) {
fputc(buf[i], fp_write);
}
fclose(fp_write);
//读文件
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "r");
if (fp_read == NULL) {
return;
}
#if 1
//判断文件结尾 注意:多输出一个空格
while (!feof(fp_read)) {
printf("%c", fgetc(fp_read));
}
#else
char ch;
while ((ch = fgetc(fp_read)) != EOF) {
printf("%c", ch);
}
#endif
}
int main()
{
test();
return 0;
}
输出结果为:
行读写函数
int fputs(const char * str, FILE * stream);
- 功能:将str所指定的字符串写入到stream指定的文件中, 字符串结束符 ‘\\0’ 不写入文件。
- 参数:
str
:字符串
stream
:文件指针 - 返回值:
成功:0
失败:-1
char * fgets(char * str, int size, FILE * stream);
- 功能:从stream指定的文件内读入字符,保存到str所指定的内存空间,直到出现换行字符、读到文件结尾或是已读了size - 1个字符为止,最后会自动加上字符 ‘\\0’ 作为字符串结束。
- 参数:
str
:字符串
size
:指定最大读取字符串的长度(size - 1)
stream
:文件指针 - 返回值:
成功:成功读取的字符串
读到文件尾或出错: NULL
行读写案例
往文件中写入四行,并读出输出。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//写文件
FILE* fp_write = NULL;
//写方式打开文件
fp_write = fopen("./mydata.txt", "w+");
if (fp_write == NULL) {
perror("fopen:");
return;
}
char* buf[] = {
"01 倩 this is a test for pfutc!\\n",
"02 倩 this is a test for pfutc!\\n",
"03 倩 this is a test for pfutc!\\n",
"04 倩 this is a test for pfutc!\\n",
};
for (int i = 0; i < 4; i++) {
fputs(buf[i], fp_write);
}
fclose(fp_write);
//读文件
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "r");
if (fp_read == NULL) {
perror("fopen:");
return;
}
//判断文件结尾
while (!feof(fp_read)) {
char temp[1024] = { 0 };
fgets(temp, 1024, fp_read);
printf("%s", temp);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
运行结果为:
块读写函数
size_t fwrite(
const void *ptr,
size_t size,
size_t nmemb,
FILE *stream
);
- 功能:以数据块的方式给文件写入内容
- 参数:
ptr
:准备写入文件数据的地址
size
:size_t
为unsigned int类型
,此参数指定写入文件内容的块数据大小
nmemb
:写入文件的块数,写入文件数据总大小为:size * nmemb
stream
:已经打开的文件指针 - 返回值:
成功:实际成功写入文件数据的块数,此值和nmemb
相等
失败:0
size_t fread(
void *ptr,
size_t size,
size_t nmemb,
FILE *stream
);
- 功能:以数据块的方式从文件中读取内容
- 参数:
ptr
:存放读取出来数据的内存空间
size
:size_t
为unsigned int类型
,此参数指定读取文件内容的块数据大小
nmemb
:读取文件的块数,读取文件数据总大小为:size * nmemb
stream
:已经打开的文件指针 - 返回值:
成功:实际成功读取到内容的块数,如果此值比nmemb
小,但大于0,说明读到文件的结尾。
失败:0
块读写案例
建立教师结构体,写入老师信息,并从文件中读取信息输出:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// 老师结构体
typedef struct _TEACHER {
char name[64];
int age;
}Teacher;
void test() {
//写文件
FILE* fp_write = NULL;
//写方式打开文件
fp_write = fopen("./mydata.txt", "wb");
if (fp_write == NULL) {
perror("fopen:");
return;
}
Teacher teachers[4] = {
{ "倩", 33 },
{ "利", 28 },
{ "Jos", 45},
{ "咪咪", 35}
};
for (int i = 0; i < 4; i++) {
fwrite(&teachers[i], sizeof(Teacher), 1, fp_write);
}
//关闭文件
fclose(fp_write);
//读文件
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
Teacher temps[4];
fread(&temps, sizeof(Teacher), 4, fp_read);
printf("输出老师们的信息:\\n");
for (int i = 0; i < 4; i++) {
printf("姓名:%s 年龄:%d\\n", temps[i].name, temps[i].age);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
运行结果为:
格式化读写函数
int fprintf(FILE * stream, const char * format, ...);
- 功能:根据参数
format
字符串来转换并格式化数据,然后将结果输出到stream指定的文件中,指定出现字符串结束符'\\0'
为止。 - 参数:
stream
:已经打开的文件
format
:字符串格式,用法和printf()
一样 - 返回值:
成功:实际写入文件的字符个数
失败:-1
int fscanf(FILE * stream, const char * format, ...);
- 功能:从
stream
指定的文件读取字符串,并根据参数format
字符串来转换并格式化数据。 - 参数:
stream
:已经打开的文件
format
:字符串格式,用法和scanf()
一样 - 返回值:
成功:实际从文件中读取的字符个数
失败: - 1
注意:fscanf遇到空格和换行时结束。
格式化读写案例
写入一行带空格的字符串,读取输出:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void test() {
//写文件
FILE* fp_write = NULL;
//写方式打开文件
fp_write = fopen("./mydata.txt", "w");
if (fp_write == NULL) {
perror("fopen:");
return;
}
fprintf(fp_write, "he llo wor ld :%d!", 99999);
//关闭文件
fclose(fp_write);
//读文件
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
char temps[1024] = { 0 };
while (!feof(fp_read)) {
fscanf(fp_read, "%s", temps);
printf("%s", temps);
}
fclose(fp_read);
}
int main()
{
test();
return 0;
}
随机读写函数
注意:这里的随机读写,不是系统随机位置就真随意读写了,是你要指定的随意位置进行读写
int fseek(FILE *stream, long offset, int whence);
- 功能:移动文件流(文件光标)的读写位置。
- 参数:
stream
:已经打开的文件指针
offset
:根据whence
来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence
往右移动,如果是负数,则相对于whence
往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了 文件末尾,再次写入时将增大文件尺寸。
whence
:其取值如下:SEEK_SET
:从文件开头移动offset个字节SEEK_CUR
:从当前位置移动offset个字节SEEK_END
:从文件末尾移动offset个字节
- 返回值:
成功:0
失败:-1
long ftell(FILE *stream);
- 功能:获取文件流(文件光标)的读写位置。
- 参数:
stream
:已经打开的文件指针 - 返回值:
成功:当前文件流(文件光标)的读写位置
失败:-1
void rewind(FILE *stream);
- 功能:把文件流(文件光标)的读写位置移动到文件开头。
- 参数:
stream
:已经打开的文件指针 - 返回值:
无返回值
随机读写案例
随机位置读取不同老师:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct _TEACHER {
char name[64];
int age;
}Teacher;
void test() {
//写文件
FILE* fp_write = NULL;
//写方式打开文件
fp_write = fopen("./mydata.txt", "wb");
if (fp_write == NULL) {
perror("fopen:");
return;
}
Teacher teachers[4] = {
{ "1倩", 33 },
{ "2利", 28 },
{ "3Jos", 45},
{ "4咪咪", 35}
};
for (int i = 0; i < 4; i++) {
fwrite(&teachers[i], sizeof(Teacher), 1, fp_write);
}
//关闭文件
fclose(fp_write);
//读文件
FILE* fp_read = NULL;
fp_read = fopen("./mydata.txt", "rb");
if (fp_read == NULL) {
perror("fopen:");
return;
}
Teacher temp;
// 从文件开头移动:读取第三个
fseek(fp_read, sizeof(Teacher) * 2, SEEK_SET);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\\n", temp.name, temp.age);
memset(&temp, 0, sizeof(Teacher));
// 从文件末尾移动:读取第四个
fseek(fp_read, -(int)sizeof(Teacher), SEEK_END);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\\n", temp.name, temp.age);
// 重新从文件开头读取
rewind(fp_read);
fread(&temp, sizeof(Teacher), 1, fp_read);
printf("Name:%s Age:%d\\n", temp.name, temp.age);
fclose(fp_read);
}
int main()
{
test();
return 0;
}
运行结果为:
文件操作综合案例
内容较多,请移驾另一篇博客:https://yangyongli.blog.csdn.net/article/det 以上是关于C语言 文件操作相关函数的主要内容,如果未能解决你的问题,请参考以下文章