目录
1.单字符文件读写
1.1 单字符读文件
1.1.1 fgetc函数
1.1.2 getc函数
1.1.3 getchar函数
1.1.4 ungetc函数
1.1.5 单字符读文件综合示例代码
1.2 单字符写文件
1.2.1 fputc函数
1.2.2 putc函数
1.2.3 putchar函数
1.2.4 单字符写文件综合示例代码
2.多字符文件读写
2.1 多字符读文件
2.1.1 fgets函数
2.1.2 gets函数
2.1.3 多字符读文件综合示例代码
2.2 多字符写文件
2.2.1 fputs函数
2.2.2 puts函数
2.2.3 多字符写文件综合示例代码
3.二进制读写
3.1 二进制读文件
3.1.1 fread函数
3.1.2 fread函数示例代码
3.2 二进制写文件
3.2.1 fwrite函数
3.2.2 fwrite函数示例代码
1.单字符文件读写
1.1 单字符读文件
1.1.1 fgetc函数
#include <stdio.h>
int fgetc(FILE *stream);
函数简介:fgetc函数是C语言中用于从文件中逐个字符读取数据的函数之一。
函数参数:
stream:要读取的文件指针。
函数返回值:
成功:返回读取的字符作为整数。
失败:读取失败或到达文件末尾,则返回EOF(End of File)。
1.1.2 getc函数
#include <stdio.h>
int getc(FILE *stream);
函数简介:getc函数是C语言中用于从文件中逐个字符读取数据的函数之一。
函数参数:
stream:要读取的文件指针。
函数返回值:
成功:返回读取的字符作为整数。
失败:读取失败或到达文件末尾,则返回EOF(End of File)。
1.1.3 getchar函数
#include <stdio.h>
int getchar(void);
函数简介:getchar函数是C语言中的一个标准库函数,用于从标准输入流(stdin)中读取一个字符。
函数参数:
无参数。
函数返回值:
成功:返回读取的字符作为整数。
失败:读取失败或到达文件末尾,则返回EOF(End of File)。
1.1.4 ungetc函数
#include <stdio.h>
int ungetc(int c, FILE *stream);
函数简介:ungetc函数是C语言标准库中的一个函数,用于将一个字符推回到输入流中。
函数参数:
c:要推回的字符。
stream:要推回的文件指针。
函数返回值:
成功:返回成功推回的字符c。
失败:返回EOF(-1)。
ungetc函数原理
图 1-1 ungetc函数原理
ungetc函数相对于其他单个字符处理函数来说,理解起来稍微困难一点,网上有很多资料讨论ungetc函数,有时候真的会被绕晕。
其实我们认真阅读一下glibc源码,就能发现ungetc函数只是将_IO_read_ptr指针后退了一个字节,然后将需要推回的字符填充至该字节,下次就能再次读到这个字节。
ungetc函数主要的作用就是一个预览的作用。
ungetc函数使用注意事项
- ungetc函数只能推回一个字符,即使传入的字符c是多字节字符。
- ungetc函数只能将字符推回到读缓冲区中,不能用于改变文件指针位置。
1.1.5 单字符读文件综合示例代码
int single_char_read_test() {
int c = 0;
#if 1
FILE *fp = fopen(TEST_FILE, "r+");
if (!fp) {
perror("fopen error");
return -1;
}
#else
FILE *fp = stdin;
#endif
c = fgetc(fp);
putchar(c);
c = getc(fp);
putchar(c);
c = getchar();
putchar(c);
ungetc('+', fp);
c = fgetc(fp);
putchar(c);
if (fp != stdin) {
fclose(fp);
}
return 0;
}
1.2 单字符写文件
1.2.1 fputc函数
#include <stdio.h>
int fputc(int c, FILE *stream);
函数简介:fputc函数是C语言中用于将一个字符写入到指定文件中的函数。
函数参数:
c:表示要写入的字符,以整数形式传递。
stream:表示要写入的文件指针。
函数返回值:
成功:返回写入成功的字符。
失败:返回EOF(-1)。
1.2.2 putc函数
#include <stdio.h>
int putc(int c, FILE *stream);
函数简介:putc函数是C语言中用于将一个字符写入到指定文件中的函数。
函数参数:
c:表示要写入的字符,以整数形式传递。
stream:表示要写入的文件指针。
函数返回值:
成功:返回写入成功的字符。
失败:返回EOF(-1)。
1.2.3 putchar函数
#include <stdio.h>
int putchar(int c);
函数简介:putchar函数是C语言标准库中的一个函数,用于将一个字符输出到标准输出流(stdout)。
函数参数:
c:表示要写入的字符,以整数形式传递。
函数返回值:
成功:返回写入成功的字符。
失败:返回EOF(-1)。
1.2.4 单字符写文件综合示例代码
int single_char_write_test() {
#if 0
FILE *fp = fopen(TEST_FILE, "r+");
if (!fp) {
perror("fopen error");
return -1;
}
#else
FILE *fp = stdout;
#endif
fputc('a', fp);
putc('b', fp);
putchar('c');
if (fp != stdout) {
fclose(fp);
}
return 0;
}
2.多字符文件读写
2.1 多字符读文件
2.1.1 fgets函数
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
函数简介:fgets函数是C语言中用于从指定的文件中读取一行数据的函数。
函数参数:
s:表示一个字符数组,用于存储读取到的字符串数据。
size:表示要读取的最大字符数。
stream:表示要读取的文件指针。
函数返回值:
成功:返回一个指向s的指针。
失败:读取失败或者已经到达文件末尾,则返回NULL。
注意事项:
- fgets函数会根据指定的size来限制读取的字符数,遇到换行符('\n')或者文件结束符(EOF)时会停止读取。
- fgets会将最后一个读到的字符替换为终止符('\0'),特别是在限制了size的情况,通常会比读到的字符数量(size)少一个字符,因为最后一个字符被替换成终止符('\0')。
2.1.2 gets函数
#include <stdio.h>
char *gets(char *s);
函数简介:gets函数是用于从标准输入(stdin)中读取一行字符串的函数,gets函数会从标准输入中读取字符,直到遇到换行符('\n')为止,并将读取到的字符存储在str所指向的字符数组中。它会自动添加字符串终止符('\0')。
由于gets函数无法检查输入字符的长度,容易导致缓冲区溢出(buffer overflow)的问题。这使得gets函数非常不安全,容易受到缓冲区溢出攻击,可能导致程序崩溃或被恶意利用。
函数参数:
s:表示一个字符数组,用于存储读取到的字符串数据。
函数返回值:
成功:返回一个指向s的指针。
失败:读取失败或者已经到达文件末尾,则返回NULL。
2.1.3 多字符读文件综合示例代码
int multil_char_read_test() {
char rbuf[BUF_SIZE] = {0};
#if 0
FILE *fp = fopen(TEST_FILE, "r+");
if (!fp) {
perror("fopen error");
return -1;
}
#else
FILE *fp = stdin;
#endif
memset(rbuf, 0, BUF_SIZE);
char *p = fgets(rbuf, 10, fp);
printf("p:%s\n", p);
printf("rbuf:%s\n", rbuf);
if (fp != stdin) {
fclose(fp);
}
return 0;
}
2.2 多字符写文件
2.2.1 fputs函数
#include <stdio.h>
int fputs(const char *s, FILE *stream);
函数简介:fputs函数是C语言中用于向指定的文件写入字符串的函数。
函数参数:
s:表示要写入的字符串数据。
stream:表示要写入的文件指针。
函数返回值:
成功:返回一个非负整数。
失败:返回EOF(-1)。
2.2.2 puts函数
#include <stdio.h>
int puts(const char *s);
函数简介:puts函数是C语言中用于向标准输出(stdout)打印字符串的函数,puts函数会将字符串打印到标准输出中,并自动在字符串末尾添加换行符('\n')。
函数参数:
s:表示要写入的字符串数据。
函数返回值:
成功:返回一个非负整数。
失败:返回EOF(-1)。
2.2.3 多字符写文件综合示例代码
int multil_char_write_test() {
char wbuf[BUF_SIZE] = {0};
#if 1
FILE *fp = fopen(TEST_FILE, "r+");
if (!fp) {
perror("fopen error");
return -1;
}
#else
FILE *fp = stdout;
#endif
#define TEST1_STRING "helloworld\n"
memset(wbuf, 0, BUF_SIZE);
memcpy(wbuf, TEST1_STRING, sizeof(TEST1_STRING));
printf("wbuf:%s\n", wbuf);
int ret = fputs(wbuf, fp);
printf("fputs ret:%d\n", ret);
if (ret == EOF) {
perror("fputs error");
goto out;
}
ret = puts(TEST_STRING);
printf("puts ret:%d\n", ret);
if (ret == EOF) {
perror("puts error");
goto out;
}
out:
if (fp != stdout) {
fclose(fp);
}
return 0;
}
3.二进制读写
3.1 二进制读文件
3.1.1 fread函数
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
函数简介:fread函数是C语言标准库中的一个函数,用于从文件中读取数据。
函数参数:
ptr:指向一个用于存储读取数据的内存区域的指针。
size:每个数据元素的字节数。
nmemb:要读取的数据元素个数。
stream:指向文件对象的指针。
函数返回值:
成功:实际成功读取的数据元素个数,通常等于参数nmemb。
失败:如果发生错误或到达文件末尾,则返回值可能小于参数nmemb(通常为0)。
3.1.2 fread函数示例代码
int fread_test() {
int ret = 0;
char rbuf[BUF_SIZE] = {0};
FILE *fp = fopen(TEST_FILE, "r+");
if (!fp) {
perror("fopen error");
return -1;
}
memset(rbuf, 0, BUF_SIZE);
int count = 2;
while((ret = fread(rbuf, 100, count, fp)) == count) {
printf("ret:%d\n", ret);
}
printf("break ret:%d\n", ret);
fclose(fp);
return 0;
}
3.2 二进制写文件
3.2.1 fwrite函数
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
函数简介:fwrite函数是C语言标准库中的一个函数,用于将数据写入文件。
函数参数:
ptr:指向要写入文件的数据的指针。
size:每个数据元素的字节数。
nmemb:要写入的数据元素个数。
stream:指向文件对象的指针。
函数返回值:
成功:实际成功写入的数据元素个数,通常等于参数nmemb。
失败:如果发生错误,则返回值可能小于参数nmemb(通常为0)。
3.2.2 fwrite函数示例代码
int fwrite_test() {
char sbuf[BUF_SIZE] = {0};
for (int i = 0; i < BUF_SIZE; i++) {
sbuf[i] = 'S';
}
FILE *fp = fopen(TEST_FILE, "w+");
if (!fp) {
perror("fopen error");
return -1;
}
int count = 5;
int ret = fwrite(sbuf, BUF_SIZE, count, fp);
printf("fwrite count:%d, ret:%d\n", count, ret);
if (ret != count) {
perror("fread error");
goto out;
}
out:
fclose(fp);
return 0;
}