I/O I/O基本概念与基本I/O函数 6.30
前言
今天我们开始I/O的学习。
I/O的学习主要以函数为主,即主要靠记忆,当然实际的工程应用过程中完全可以开卷,但出于对生产力的考量,依旧需要主动记忆大量内容。
概述
1.I/O基本概念(含笔记与导图)
2.cat的实现
3.文件cp的实现
4.计算文件行数的实现
1.I/O基本概念(含笔记与导图)
一、I/O 基本概念
-
文件输入(读取)
-
数据从 硬盘(存储设备) 读取到 内存 中。
-
示例程序:
/a.out
-
-
文件输出(写入)
-
数据从 内存 写入到 硬盘(存储设备) 中。
-
二、存储设备对比(硬盘 vs 内存)
特性 | 硬盘(SID) | 内存(ARM) |
---|---|---|
容量 | 空间大 | 空间小 |
速度 | 较慢 | 速度快 |
持久性 | 数据持久存储(非易失性) | 断电后数据丢失(易失性) |
访问方式 | 按键不直接接触 | 按键直接接触 |
三、标准 I/O 与文件 I/O 的区别
类型 | 交互对象 | 特点 |
---|---|---|
标准 I/O | 程序 ↔ 用户 | 缓冲机制、高可移植性 |
文件 I/O | 程序 ↔ 操作系统 | 依赖系统、低可移植性 |
四、标准 I/O 关键特性
特性 | 描述 |
---|---|
缓冲区 | 减少直接系统调用,提高效率 |
速度 | 较快(缓冲优化) |
调用方式 | 库函数(如 fprintf 、fscanf ) |
可移植性 | 高(跨平台兼容) |
操作对象 | 流指针(FILE* ) |
支持资源 | 文件、标准输入/输出(stdin/stdout) |
五、常用标准 I/O 函数列表
-
文件操作
-
FILE* fopen(const char* filename, const char* mode);
-
int fclose(FILE* stream);
-
-
错误处理
-
void perror(const char* s);
-
char* strerror(int errno);
-
-
字符 I/O
-
int fputc(int c, FILE* stream);
-
int fgetc(FILE* stream);
-
-
文件定位
-
int fseek(FILE* stream, long offset, int origin);
-
void rewind(FILE* stream);
-
long ftell(FILE* stream);
-
-
字符串 I/O
-
int fputs(const char* str, FILE* stream);
-
char* fgets(char* str, int size, FILE* stream);
-
-
格式化 I/O
-
int fprintf(FILE* stream, const char* format, ...);
-
int fscanf(FILE* stream, const char* format, ...);
-
六、注意事项
-
资源释放:使用
fclose
及时关闭文件,避免资源泄漏。 -
错误检查:调用
perror
或strerror
诊断 I/O 错误。 -
缓冲机制:标准 I/O 默认启用缓冲,可通过
setbuf
调整。
思维导图与手写笔记如下:
附:I/O的基本操作
#include <IO_head.h>
int main(int argc, const char *argv[])
{//打开文件FILE* file_p = fopen("./my.txt","w+");if(file_p==NULL){ERROR("fopen failed");}//if(file_p==NULL){perror("fopen failed");return -1;}//printf("%s\n",strerror(errno));//printf("fopen failed\n")else{printf("fopen succeeded\n");}//写文件if(fputc('a',file_p)==-1){printf("fputc failed\n");return -1;}else{printf("fputc succeeded\n");}//计算文件大小long len = ftell(file_p);printf("length of file: %ld\n",len);//光标的偏移rewind(file_p);/*if(fseek(file_p,0,SEEK_SET)==-1){ERROR("fseek failed\n");}else{printf("fseek succeeded\n");}*///读文件char buf = (char)fgetc(file_p);if(buf==EOF){printf("fgets failed\n");}else{printf("fgets succeeded:buf=%c\n",buf);}//关闭文件: //fclose(FILE* file_p){return 0;/return EOF;#define EOF (-1))}if(fclose(file_p)==EOF){ERROR("fclose failed");}else{printf("fclose succeeded\n");}return 0;
}
ubuntu@ubuntu:~/IO/class1$ ./04_fseek
fopen succeeded
fputc succeeded
length of file: 1
fgets succeeded:buf=a
fclose succeeded
ubuntu@ubuntu:~/IO/class1$
2.cat的实现
2.1.codes
#include <IO_head.h>
int main(int argc, const char *argv[])
{//读取外部传参if(argc<2){printf("erroe");}FILE* file_p = fopen(*(argv+1),"r");if(file_p==NULL){ERROR("fopen failed");}else{printf("fopen succeeded\n");}//实现cat的功能char buf[128] = {0};rewind(file_p);while(1){memset(buf, 0, sizeof buf);//读取//char* fgets(char* s, int len, FILE* stream){...return s;}if(fgets(buf, sizeof buf, file_p)==NULL){printf("fgets failed\n");break;}buf[strcspn(buf, "\n")] = '\0';//buf[strlen(buf)-1]='\0';//printf("fgets succeeded\n");printf("buf = [%s]\n",buf);}return 0;
}
2.2.run
ubuntu@ubuntu:~/IO/class1$ ./h1 my.txt
fopen succeeded
buf = [abcd]
buf = [efg]
buf = [hi]
buf = [j]
fgets failed
ubuntu@ubuntu:~/IO/class1$
此处./h1相当于cat
注意:没有写fclose,因为累了......
3.文件cp的实现
3.1.codes
#include <IO_head.h>
int main(int argc, const char* argv[]){//欲将键入的文件进行拷贝,至少需要一个原文件,一个目标文件if(argc<3)printf("error");//获取外部传参FILE* file_2_p = fopen(*(argv+2),"r");FILE* file_1_p = fopen(*(argv+1),"w");char buf[128]={0};while(1){memset(buf,0,sizeof buf);if(fgets(buf,sizeof buf,file_2_p)!=NULL){printf("fgets succeeded\n");}else{printf("fgets failed\n");break;}if(fputs(buf,file_1_p)!=EOF){printf("fputs succeeded\n");}else{printf("fgets failed\n");break;}}return 0;
}
3.2.run
ubuntu@ubuntu:~/IO/class1$ ./h2 new.text my.txt
fgets succeeded
fputs succeeded
fgets succeeded
fputs succeeded
fgets succeeded
fputs succeeded
fgets succeeded
fputs succeeded
fgets failed
ubuntu@ubuntu:~/IO/class1$ ./h1 new.text
fopen succeeded
buf = [abcd]
buf = [efg]
buf = [hi]
buf = [j]
fgets failed
ubuntu@ubuntu:~/IO/class1$
此处./h2相当于cp
注意:同理,没有写fclose,因为累了......
4.计算文件行数的实现
4.1.codes
#include <IO_head.h>
int main(int argc, const char* argv[]){//获取外部传参if(argc<2)printf("error\n");FILE* file_p = fopen(*(argv+1),"r");//循环计算行数char buf[128]={0};int len = 0;while(1){memset(buf,0,sizeof buf);if(fgets(buf,sizeof buf, file_p)!=NULL){len++;}else{break;}}printf("有%d行\n",len);return 0;
}
4.2.run
ubuntu@ubuntu:~/IO/class1$ ./h3 my.txt
有4行
ubuntu@ubuntu:~/IO/class1$
此处./h3相当于计算行数的函数。
注意:同理,没有写fclose,因为累了......
结语
以上。