文件读写

4.4k 词

文件读写字符函数

fgetc

从文件中读取一个字符

1
int fgetc(FILE *fp);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *fp = NULL;
fp = fopen("test.txt", "r");
if (fp == NULL)
{
printf("文件打开失败\n");
return 0;
}
int ch = fgetc(fp);
while (ch != EOF)
{
printf("%c", ch);//打印字符
ch = fgetc(fp);
}
fclose(fp);
return 0;

}

返回值:

  • 成功:返回读取到的字符
  • 失败:返回EOF

参数:

  • fp:要读取的文件指针

读取字符的方式:

  • 从文件指针的位置开始读取
  • 每次读取一个字符
  • 读取到的字符会自动转换为ASCII码

读取字符的结束条件:

  • 读取到文件末尾
  • 读取到文件结束符EOF

fgets

从文件中读取一行字符

1
char *fgets(char *str, int n, FILE *fp);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *fp = NULL;
fp = fopen("test.txt", "r");
if (fp == NULL)
{
printf("文件打开失败\n");
return 0;
}
char str[100];
while (fgets(str, 100, fp) != NULL)
{
printf("%s", str);
}
fclose(fp);
return 0;

}

返回值:

  • 成功:返回读取到的字符串
  • 失败:返回NULL

参数:

  • str:要读取的字符串
  • n:读取的字符数
  • fp:要读取的文件指针

读取字符串的方式:

  • 从文件指针的位置开始读取
  • 每次读取一行字符
  • 读取到的字符会自动转换为ASCII码
  • 读取完成后在输出的字符串末尾添加\0

读取字符串的结束条件:

  • 读取到文件的换行符
  • 读取到文件的size-1个字符
  • 读取到文件结束符EOF

fputc

向文件中写入一个字符

1
int fputc(int ch, FILE *fp);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *fp = NULL;
fp = fopen("test.txt", "w");
if (fp == NULL)
{
printf("文件打开失败\n");
return 0;
}
int ch = 'a';
while (ch <= 'z')
{
fputc(ch, fp);
ch++;
}
fclose(fp);
return 0;

}

返回值:

  • 成功:返回写入的字符
  • 失败:返回EOF

参数:

  • ch:要写入的字符
  • fp:要写入的文件指针

写入字符的方式:

  • 从文件指针的位置开始写入
  • 每次写入一个字符
  • 写入的字符会自动转换为ASCII码

fputs

向文件中写入字符串

1
int fputs(const char *str, FILE *fp);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

int main()
{
FILE *fp = NULL;
fp = fopen("test.txt", "w");//以写入的方式打开文件
if (fp == NULL)
{
printf("文件打开失败\n");
return 0;
}
char str[] = "hello world";
fputs(str, fp);
fclose(fp);
return 0;

}

返回值:

  • 成功:返回写入的字符串
  • 失败:返回EOF

参数:

  • str:要写入的字符串
  • fp:要写入的文件指针

写入字符串的方式:

  • 从文件指针的位置开始写入
  • 写入的字符会自动转换为ASCII码

写入字符串的结束条件:

  • 读取到字符串的末尾
  • 读取到字符串的换行符
  • 读取到字符串的\0

文件读写函数

fread

从文件中读取数据

1
2
3
4
5
size_t fread(
void *ptr,
size_t size,
size_t nmemb,
FILE *stream);

fread函数从stream标识的文件中读取数据,一元素的大小由size决定,共nmemb个元素,存放在ptr指定的内存中。

返回值:

  • 成功:返回实际读取到的元素个数
  • 失败:返回0

参数:

  • ptr:要读取的数据的地址
  • size:每个元素的大小
  • nmemb:要读取的元素个数
  • stream:要读取的文件指针

读取数据的方式:

  • 从文件指针的位置开始读取
  • 每次读取一个元素
  • 读取到的数据会自动转换为ASCII码

fwrite

向文件中写入数据

1
2
3
4
5
size_t fwrite(
const void *ptr,
size_t size,
size_t nmemb,
FILE *stream);

fwrite函数向stream标识的文件中写入数据,一元素的大小由size决定,共nmemb个元素,从ptr指定的内存中读取。

返回值:

  • 成功:返回实际写入的元素个数
  • 失败:返回0

参数:

  • ptr:要写入的数据的地址
  • size:每个元素的大小
  • nmemb:要写入的元素个数
  • stream:要写入的文件指针

写入数据的方式:

  • 从文件指针的位置开始写入
  • 每次写入一个元素
  • 写入的数据会自动转换为ASCII码

注意

  • fread/fwrite函数读写数据时,会自动跳过文件中的空格、换行符等字符
  • fread/fwrite函数可以将文件的内容解析为结构体等其他格式进行读写,而非字符类型的数据会以二进制格式保存在文件中
    例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>

typedef struct
{
int a;
int b;
char c;
}MSG;


int main(int * argc, char * argv[])
{
FILE * fp = fopen("./test.txt", "w+");
if(fp == NULL)
{
printf("error\n");
return -1;
}

MSG msg[4] = {1, 2, 'a', 3, 4, 'b', 5, 6, 'c', 7, 8, 'd'};
fwrite(msg, sizeof(MSG), 4, fp);//先将结构体写入文件


rewind(fp); //将文件指针重新定位到文件开头
MSG rcv[4];
fread(rcv, sizeof(MSG), 4, fp);

for(int i = 0; i < 4; i++){
printf("%d %d %c\n", rcv[i].a, rcv[i].b, rcv[i].c);
}

return 0;
}

fscanf

从文件中读取格式化数据

1
2
3
4
int fscanf(
FILE *stream,
const char *format,
...);

fscanf函数从stream标识的文件中读取格式化数据,格式由format指定,参数由...指定。

用例:

1
2
3
4
5
6
7
8
9
10
#include <stdio.h>

int main(int * argc, char * argv[])
{
FILE * fp = fopen("./test.txt", "w+");
//这里省略对fp的异常处理的代码段
fscanf(fp, "%d %d %d", &a, &b, &c);
printf("a = %d, b = %d, c = %d\n", a, b, c);
return 0;
}

文件:

1
1 2 3

输出结果:

1
a = 1, b = 2, c = 3

返回值:

  • 成功:返回读取的参数个数
  • 失败:返回EOF

参数:

  • stream:要读取的文件指针
  • format:要读取的格式化字符串
  • …:要读取的参数

fprintf

向文件中写入格式化数据

1
2
3
4
int fprintf(
FILE *stream,
const char *format,
...);

fprintf函数向stream标识的文件中写入格式化数据,格式由format指定,参数由...指定。

返回值:

  • 成功:返回写入的字符个数
  • 失败:返回EOF

参数:

  • stream:要写入的文件指针
  • format:要写入的格式化字符串
  • …:要写入的参数

写入数据的方式:

  • 从文件指针的位置开始写入
  • 每次写入一个字符
  • 写入的数据会自动转换为ASCII码


文件的随机读写

在之前的文件指针操作中,介绍了对文件指针的读取位置进行操作和查询的函数,结合文件读写函数就可以实现对文件内容的随机读写。
而除了文件指针操作中介绍的ftell fseek rewind 函数是对文件指针的位置偏移量进行操作

这里我们再介绍两个函数fgetpos fsetpos,这两个函数是直接操作文件指针的位置
使用fgetpos fsetpos可以将文件中的特殊读写位置直接写入到fpos_t类型的变量中,在读写后快速将指针返回到变量储存的位置中,而不需要间接保存偏移量。这样可以确保在文件中进行非顺序操作时不会丢失数据。

fgetpos

获取文件指针当前位置

1
2
3
int fgetpos(
FILE *stream,
fpos_t *pos);

fgetpos函数获取stream标识的文件指针当前位置,并保存在pos中。

返回值:

  • 成功:返回0
  • 失败:返回非0

参数:

  • stream:要获取的文件指针
  • pos:保存文件指针当前位置的变量

fsetpos

将文件指针移动到指定位置

1
2
3
int fsetpos(
FILE *stream,
const fpos_t *pos);

fsetpos函数将stream标识的文件指针移动到pos指定的位置。

返回值:

  • 成功:返回0
  • 失败:返回非0

参数:

  • stream:要移动的文件指针
  • pos:要移动到的位置