- (꒪ꇴ꒪ ),hello我是祐言
- 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
- 快上🚘,一起学习!
- 送给读者的一句鸡汤🤔:
- 集中起来的意志可以击穿顽石!
- 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏
标准IO函数
标准IO函数是C语言标准库提供的一组用于输入和输出的函数,通常是以缓冲区为基础实现
【玩转Linux】标准io缓冲区的操作_祐言QAQ的博客-CSDN博客
的,可以提高程序的性能和效率。标准IO函数还可以通过文件指针操作文件,今天主要来学习一些常见的标准IO函数以及通过文件指针操作文件。
1.fopen() / fclose()
(1)功能:
fopen():打开一个文件,返回一个文件指针,用于后续对文件的读写操作。
fclose():关闭一个已打开的文件,释放相关资源。
(2)头文件:
fopen()和fclose()函数需要包含头文件 <stdio.h>。
(3)原型:
fopen():FILE *fopen(const char *filename, const char *mode);
fclose():int fclose(FILE *stream);
(4)返回值:
fopen()
:如果文件打开成功,返回指向该文件的文件指针;如果打开失败,返回NULL
。fclose()
:成功关闭文件返回0,关闭失败返回非零值。
(5)示例:
FILE* fp = fopen("example.txt", "r"); // 以只读方式打开文件
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
// 读取文件内容
char buffer[10] = "hello";
fgets(buffer, 10, fp);
printf("文件内容:%s\n", buffer);
fclose(fp); // 关闭文件
想必大家看到这个例子也很懵,在fopen函数中的这个“r”是什么,其实这是打开文件的模式(mode),它一共有六种,分别是:
2.fgetc()和getc()和getchar(),以及fputc()和putc()和putchar()
(1)功能:
fgetc():从文件中读取一个字符。
getc():从文件中读取一个字符。
getchar():从标准输入中读取一个字符。
fputc():将一个字符写入文件。
putc():将一个字符写入文件。
putchar():将一个字符写入标准输出。
(2)头文件:
上述函数需要包含头文件 <stdio.h>。
(3)原型:
fgetc():int fgetc(FILE *stream);
getc():int getc(FILE *stream);
getchar():int getchar(void);
fputc():int fputc(int ch, FILE *stream);
putc():int putc(int ch, FILE *stream);
putchar():int putchar(int ch);
值得注意的是:
fgetc()是函数
getc()是宏//getc(stdin)等同于getchar()
stream:己经打开的文件流
getchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符
fputc()是函数
putc()是宏//putc('a',stdout)等同于putchar('a')
stream:已经打开的文件流
putchar()只能从标准输入流(键盘)获取一个字符,getc()和fgetc()可以自定义从文件流读取一个字符
(4)返回值:
fgetc()
、getc()
、getchar()
:返回读取的字符的ASCII码值。fputc()
、putc()
、putchar()
:返回写入的字符的ASCII码值。
(5)示例:
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
// 读取文件内容并输出
int c;
while ((c = fgetc(fp)) != EOF) {
putchar(c);
}
fclose(fp);
FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
printf("打开文件失败\n");
return 1;
}
// 向文件中写入数据
fputc('H', fp2);
fputc('e', fp2);
fputc('l', fp2);
fputc('l', fp2);
fputc('o', fp2);
fclose(fp2);
3.fgets()/gets()/fputs()/puts()
(1)功能:
fgets():从文件中读取一行字符。
gets():从标准输入中读取一行字符。
fputs():将一行字符写入文件。
puts():将一行字符写入标准输出。
(2)头文件:
上述函数需要包含头文件 <stdio.h>。
(3)原型:
char *fgets(char *str, int n, FILE *stream);
char *gets(char *str);
int fputs(const char *str, FILE *stream);
int puts(const char *str);
(4)返回值:
fgets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
gets():成功读取字符返回 str 的地址;读取失败或到达文件末尾返回 NULL。
fputs():成功写入字符返回非负值;写入失败返回 EOF。
puts():成功写入字符返回非负值;写入失败返回 EOF。
(5)示例:
// 打开一个文件
FILE *fp = fopen("1.txt", "r+"); //以读写打开文件,但是要求文件必须存在
if(fp == NULL)
{
perror("fopen() fail");
exit(errno);
}
// 从文件中读取一个字符
int ch = fgetc(fp);
printf("ch = %c\n", ch);
ch = getc(fp);
printf("ch = %c\n", ch);
getchar(); //默认从标准输入读取 getc(stdin);
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
FILE* fp2 = fopen("output.txt", "w");
if (fp2 == NULL) {
printf("打开文件失败\n");
return 1;
}
// 向文件中写入数据
fputs("Hello, world!\n", fp2);
fputs("This is a test.\n", fp2);
fclose(fp2);
FILE *fp = fopen("1.txt", "r+"); // 以读写打开文件,要求文件必须存在
if (fp == NULL) {
perror("fopen() fail");
exit(errno);
}
// 从文件中读取一个字符
int ch = 'A';
fputc(ch, fp);
putc('B', fp);
// 将文件指针移动到文件开头
fseek(fp, 0, SEEK_SET);
// 从文件中读取一个字符并打印到终端
int read_ch = fgetc(fp);
putchar(read_ch);
fclose(fp); // 关闭文件
return 0;
}
值得注意的有以下几点:
(1)fgets()跟fgetc()一样,当其返回NULL时并不能确定究竟是达到文件末尾还是碰到错误,需要用feof()/ferror()来进一步判断。
(2)fgets()每次读取至多不超过size个字节的一行,所谓“一行”即数据至多包含一个换行符'\n'。
(3)gts()是一个已经过时的接口,因为他没有指定自定义缓冲区s的大小,这样很容易造成缓冲区溢出,导致程序段访问错误。
(4)fgets()和fputs(),gets()和puts()一般成对使用,鉴于gets()的不安全性,一般建议使用前者。
4.feof()/ferror()
功能:
feof():检查文件流的文件结束标志,判断是否已经读取到文件末尾。
ferror():检查文件流的错误标志,判断文件读取是否出错。
头文件:
上述函数需要包含头文件 <stdio.h>。
原型:
feof():int feof(FILE *stream);
ferror():int ferror(FILE *stream);
返回值:
feof():如果到达文件末尾,返回非零值(true);否则返回0(false)。
ferror():如果文件读取出错,返回非零值(true);否则返回0(false)。
示例:
// 打开一个文件
FILE *fp = fopen("1.txt", "a+"); //以读写打开文件,但是要求文件必须存在
if(fp == NULL)
{
perror("fopen() fail");
exit(errno);
}
while(1)
{
int ch = fgetc(fp);
if(ch == EOF)
{
if(feof(fp)) //为真,说明文件读到末尾
{
printf("文件已读完\n");
break;
}
if(ferror(fp)) //为真,说明文件读取出错
{
perror("fgetc() fail");
exit(errno);
}
}
// 输出到屏幕
printf("%c\n", ch);
}
// 关闭文件
fclose(fp);
5.fread(/fwrite()
功能:
fread():从文件中读取一段数据。
fwrite():将一段数据写入文件。
头文件:
上述函数需要包含头文件 <stdio.h>。
原型:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
返回值:
fread():返回实际成功读取的数据项数量,如果出错或到达文件末尾,返回值可能小于 nmemb。
fwrite():返回实际成功写入的数据项数量,如果出错,返回值可能小于 nmemb。
示例:
struct student {
char name[20];
int age;
};
// 写入结构体数据到文件中
struct student s1 = {"Tom", 18};
FILE* fp = fopen("example.bin", "wb");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
fwrite(&s1, sizeof(struct student), 1, fp);
fclose(fp);
// 从文件中读取结构体数据
struct student s2;
fp = fopen("example.bin", "rb");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
fread(&s2, sizeof(struct student), 1, fp);
printf("姓名:%s,年龄:%d\n", s2.name, s2.age);
fclose(fp);
6.fseek()/ftell()/rewind
功能:
fseek():在文件中定位指针的位置,用于设置文件指针的位置。
ftell():获取文件指针当前位置的偏移量。
rewind():将文件指针重新定位到文件的起始位置。
头文件:
上述函数需要包含头文件 <stdio.h>。
原型:
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
void rewind(FILE *stream);
返回值:
fseek():成功定位文件指针返回0,失败返回非零值。
ftell():返回当前位置的偏移量。如果出错,返回 ftell() 出错的标识值 (-1)。
rewind():无返回值。
示例:
FILE* fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
// 获取文件大小
fseek(fp, 0, SEEK_END);
long size = ftell(fp);
printf("文件大小:%ld\n", size);
// 将文件指针移回文件开头
rewind(fp);
// 读取文件内容并输出
char buffer[100];
while (fgets(buffer, 100, fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
7.printf()/fprintf()/sprintf()/snprintf()/scanf()/fscanf()/sscanf()
功能:
printf():将格式化的数据输出到标准输出。
fprintf():将格式化的数据输出到指定文件。
sprintf():将格式化的数据输出到字符数组。
snprintf():格式化数据输出到字符数组,并限制输出的字符数量。
scanf():从标准输入读取格式化数据。
fscanf():从指定文件读取格式化数据。
sscanf():从字符数组读取格式化数据。
头文件:
上述函数需要包含头文件 <stdio.h>。
原型:
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
返回值:
printf():成功打印字符数。
fprintf():成功写入字符数,失败返回负值。
sprintf():成功写入字符数。
snprintf():成功写入字符数(不包括末尾的空字符),如果截断输出返回欲写入的字符数。
scanf():成功读取的参数个数。
fscanf():成功读取的参数个数。
sscanf():成功读取的参数个数。
示例:
// 格式化输出数据到标准输出设备
int num = 123;
printf("数字:%d\n", num);
// 格式化输出数据到文件
FILE* fp = fopen("output.txt", "w");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
fprintf(fp, "数字:%d\n", num);
fclose(fp);
// 将格式化数据写入字符串中
char str[20];
sprintf(str, "数字:%d\n", num);
printf("%s", str);
// 将格式化数据写入指定长度的字符串中
char str2[10];
snprintf(str2, 10, "数字:%d\n", num);
printf("%s", str2);
// 从标准输入设备读取数据
int num2;
printf("请输入一个数字:");
scanf("%d", &num2);
printf("输入的数字:%d\n", num2);
// 从文件中读取数据
fp = fopen("example.txt", "r");
if (fp == NULL) {
printf("打开文件失败\n");
return 1;
}
fscanf(fp, "数字:%d", &num2);
printf("从文件中读取的数字:%d\n", num2);
fclose(fp);
// 从字符串中读取数据
char str3[20] = "数字:456";
sscanf(str3, "数字:%d", &num2);
printf("从字符串中读取的数字:%d\n", num2);
关于格式控制符的一些解释:
格式控制符用于指定数据的输出格式。以下是常见的格式控制符:
整数类型:
%d:有符号十进制整数
%u:无符号十进制整数
%o:无符号八进制整数
%x:无符号十六进制整数(小写字母)
%X:无符号十六进制整数(大写字母)
浮点数类型:
%f:浮点数(以小数形式输出)
%e:浮点数的指数表示(科学计数法,小写字母)
%E:浮点数的指数表示(科学计数法,大写字母)
%g:根据实际值自动选择%e或%f格式输出
字符类型:
%c:字符
%s:字符串
指针类型:
%p:指针的地址值(以十六进制输出)
布尔类型:
%d 或 %i:整数输出(0表示假,非零表示真)
特殊控制符:
%%:输出百分号符号 %
这些格式控制符可以用于 printf()、fprintf()、sprintf()、snprintf() 等输出函数,根据需要选择适合的格式控制符进行数据输出。
更多C语言和Linux系统相关文章,关注专栏:
手撕C语言
玩转linux
📢写在最后
- 今天的分享就到这啦~
- 觉得博主写的还不错的烦劳
一键三连喔
~ - 🎉感谢关注🎉