一、系统与标准IO的区别
相同点:系统IO与标准IO都可以操作linux系统下的文件。
⭐不同点:
系统IO:打开文件得到的是一个整数,称为文件描述符。
标准IO:打开文件得到的是一个指针,称为文件指针。
系统IO:可以访问linux系统下的一切文件,例如:普通文件,设备文件 ,链接文件 ,管道文件 .....
标准IO:只能访问Linux系统下的普通文件。
系统IO: 不带缓存区,数据直接写入文件。
标准IO: 带缓存区,数据写入缓存区,再写入文件中。
标准IO可以在任意的操作系统使用他是C语言库函数提供的,系统IO只能在Linux操作系统使用。
总结:在Linux系统下访问💥《普通文件》💥时,一般采用标准IO接口,因为标准IO接口丰富,且写入的效率较高!
二、标准IO接口的使用
man 3 fopen 查看打开函数
1、fopen 打开文件
NAME
fopen, fdopen, freopen - stream open functions
打开文件函数
SYNOPSIS
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
pathname:需要打开的文件路径名
mode:权限
"r" 只读
"r+" 读写 ✔️
"w" 只写,清空和如果不存在,则创建文件
"w+" 读写,清空和如果不存在,则创建文件
"a" 只写,追加,如果不存在则创建
"a+" 读写,追加,如果不存在则创建
返回值: 成功 返回文件指针 FILE *
失败 NULL
例子:以读写方式打开文件
FILE *fp = fopen("my.txt","r+");
权限表格
2、fwrite 写入文件
man 3 fwrite 查看写入接口
注意:write 函数可以写入一切数据类型,char ,short , int ,float ........
NAME
fread, fwrite - binary stream input/output
二进制 流 输入/输出
SYNOPSIS
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_t nmemb,
FILE *stream);
ptr:数据的缓存区
size:一个数据的大小,例如:char 大小为1 ,short 大小为2,int 大小为 4 .....
nmemb:需要写入数据的个数
stream: 文件指针 FILE *
返回值: 成功 写入数据的大小
失败 -1
例子:
1.写入 5 个字符
char str[10] = {"hello"};
fwrite(str,1,5,fp); //一个 char字符大小为 1 , 字符串中包含 5 个字符。
2.写入 3 个short
short buf[10]={1,2,3};
fwrite(buf,2,3,fp); //一个 short字符大小为 2 , 数组中包含 3 个short。
3.写 5 个 int
int val[]={1,2,3,4,5};
fwrite(buf,4,5,fp); //一个 int字符大小为 4 , 数组中包含 5 个int。
3、fread 读取文件
man 3 fread 查看读取接口
NAME
fread, fwrite - binary stream input/output
SYNOPSIS
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
ptr:数据的缓存区
size:一个数据的大小
nmemb:读取数据的个数
stream:文件指针FILE *
返回值: 成功 读取数据的大小
0 文件读取完毕
-1 读取错误
例子:读取一个文件中的字符串
char buf[1024]={0};
fread(buf,1,1024, fp);
读取一个 int ,文件保存的数据格式必须为 int
int value=0;
fread(&value,4,1, fp);
读取多个 int
int arry[1024]={0};
fread(arry,4,1024, fp);
4、fseek 文件光标
man 3 fseek 查看文件光标函数
NAME
fgetpos, fseek, fsetpos, ftell, rewind - reposition a stream
修改文件光标
SYNOPSIS
#include <stdio.h>
int fseek(FILE *stream, long offset, int whence);
stream:文件流指针
offset:偏移量
whence:参考位置 SEEK_SET 头, SEEK_CUR当前位置, or SEEK_END 末尾
返回值:成功 0 失败 -1
//获取当前文件光标的偏移量
long ftell(FILE *stream);
//把文件光标偏移到文件头
void rewind(FILE *stream); 等价于👉 fseek(stream, 0, SEEK_SET)
5、fclose 关闭文件
NAME
fclose - close a stream
SYNOPSIS
#include <stdio.h>
int fclose(FILE *stream);
三、main函数传递参数
#include <stdio.h>
// argc:记录用户输入参数的个数 ,例如: cp file.txt msg.txt ,所有当前cp程序的个参数为 3
// argv:记录用户输入的参数值 ,argv指针数组,argv[0]=>cp, argv[1]=>file.txt,argv[2]=>msg.txt
int main(int argc, char *argv[])
{
printf("参数的个数argc=%d\n", argc);
printf("第一参数的值:argv[0]=%s\n", argv[0]);
printf("第二参数的值:argv[1]=%s\n", argv[1]);
printf("第三参数的值:argv[2]=%s\n", argv[2]);
}
四、标准IO的缓存区
Linux系统的缓存方式
1.不缓冲类型:系统IO接口都是不缓冲的例如: read/write
一旦有数据,立刻将数据冲洗到文件
2.全缓冲类型:系统IO接口基本上都是全缓存例如: fread/fwrite ....
一旦填满缓冲区,立刻将数据冲洗到文件 ,👉 4096个字节后满
程序正常退出时,立刻将数据冲洗到文件 ,👉 main函中return 0
遇到 fflush() 强制冲洗时,立刻将数据冲洗到文件 ,👉fflush()强制刷新
关闭文件时,立刻将数据冲洗到文件 , 👉fclose() 关闭刷新。
改变缓冲区类型时,立刻将数据冲洗到文件 ,👉setvbuf() 设置缓存类型
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
stream:需要设置的文件指针
buf:缓存地址
mode:缓存方式
_IONBF unbuffered
_IOLBF line buffered
_IOFBF fully buffered
size:缓存区大小
3.行缓冲类型: 👉printf
同全缓冲类型
一旦遇到’\n’时,立刻将数据冲洗到文件 ✔️
😘温馨提示:在调用标准IO接口时记住缓存区即可!
五、标准IO数据流操作
数据流操作就是每次只操作文件中的一个字节的数据!
#include <stdio.h>
int fgetc(FILE *stream); //从文件stream中获取一个字符的数据并返回
int fputc(int c, FILE *stream); //把字符 c 输出到 stream 中文件中
六、标准IO数据行操作
数据行操作就是每次操作文件中的一行数据"\n"!
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream); //从一个文件获取数据,当大小为size 或者 遇到 \n 结束获取
stream:获取数据的文件
s:数据缓存区
size:数据的大小
int fputs(const char *s, FILE *stream); //不会自动换行,遇到\0则停止输出数据到文件中。
s:数据的缓存区
stream:输入数据的文件指针
七、⭐标准IO格式化操作
1、格式化输出
man 3 printf 查看格式化输出
int printf(const char *format, ...); //把format 格式的数据出到标准输出设备中,stdout
👉等价于fprintf(stdout, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...); //把format 格式的数据出到stream 文件指针中
int sprintf(char *str, const char *format, ...); //把format 格式的数据出到 char *str 缓存地址中
应用场景:
字符串拼接
char city[100]={"广东省"};
char Street[100]={"广州市从化区鳌头大道"};
char all[200]={0};
sprintf(all,"%s%s",city,Street); 👉广东省广州市从化区鳌头大道
数据类型转换
int value =10086;
char buf[1024];
sprintf(buf,"%d",value); //把int 转换为 char *
int snprintf(char *str, size_t size, const char *format, ...); //snprintf可以指定拼接字符串的大小为 size
2、格式化输入
man 3 scanf 查看格式化输入
#include <stdio.h>
int scanf(const char *format, ...); //从键盘中获取format格式的数据
等价于 fscanf(stdin, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...); //从 stream 文件中获取 format 格式的数据
int sscanf(const char *str, const char *format, ...);//从 str 缓存区中获取 format 格式的数据
应用场景:
字符串分割
char buf[1024]={"你好 世界"};
char str[100];
char str1[100];
sscanf(buf,"%s %s",str,str1); //str -> 你好 , str1 -> 世界
字符串类型转换
char buf[100]={"10086"};
int value=0;
sscanf(buf,"%d",&value); // char * -> int
至此,希望看完这篇文章的你有所收获,我是Bardb,译音八分贝,道友,下期见!