- IO
- 标准IO,文件IO
- 进程
- 进程的创建,线程间通讯
- 线程的创建和线程同步互斥
- Linux系统库
- 静态库,动态库
1> std:标准的
2> lO:输入输出,目前接触的是向终端进行输入输出
/usr/include <-----库文件存放文件目录
1> 标准IO: 库函数实现
2> 文件IO:系统调用实现 函数库:#include
1> 系统调用:
从用户空间到内核空间的一次切换过程
不同的系统,进入内核空间的方式是不同的,所以,接口函数有所不同
但是,只要从用户空间,切换到内核空间,就会发生系统调用,效率比较低
2> 库函数:
库函数是对系统调用的封装: 缓冲区+系统调用
库函数有缓冲区,系统调用没有缓冲区
- 标准IO: printf、scanf、puts、 gets、 getchar、 putchar; fopen、 fclose、 fprintf、 fscanf、fputs、fgets、fgetc、fputc、fread、fwrit。。。。
- 文件lO: open、close、read、write。。。
什么是FILE结构体
在Linux中,FILE结构体是一个用于管理文件I/O操作的结构体。它包含有关打开文件的信息,如文件描述符、缓冲区指针、读/写位置和错误状态等。在C语言中,FILE结构体通常以指针形式进行处理,用于访问文件。通过FILE结构体,可以进行文件的读写操作,以及控制文件的位置和状态等。在标准C库中,定义了一组用于处理文件I/O的函数,如fopen()、fclose()、fread()、fwrite()等,这些函数使用FILE结构体进行文件操作。
1. cd 到 /usr/include 目录下
2. 创建索引文件: ctags -R
3. 追代码: vi -t 函数/变量名
4. 使用: ctrl +],进行继续深层追代码
5. 返回上一级: ctrl +t
6. 在/usr/include 路径下: sudo ctags -R 生成索引文件 (tags)
7. 在当前目录下: vi -t FILE 追该名字的出处
struct _IO_FIFE{
char* _IO_read_end;
char* _IO_read_base;
}
1. 对于文件的操作,都需要使用文件指针来完成
2. 自定义文件指针: FILE*fp;
3. 系统提供的特殊文件指针: stdin(标准输入)、stdout (标准输出指针)、stderr (标准出错)
头文件 :<stdio.h>
函数原型 :FILE *fopen(const char *pathname,const char *mode);
函数功能 :使用标准TO打开一个文件
参数1 :文件路径,字符串
参数2 :也是一个字符串,打开模式 r,r+,w,w+,a,a+
返回值 :打开成功返回文件地址,失败返回NULL,并置位错误码
输入参数 | 模式 |
---|---|
r | 只读模式,如果文件不存在,则打开失败,指针定位在文件开头 |
r+ | 可读+可写,指针定位在文件开头 |
w | 只写模式,如果文件不存在,则创建文件;如果文件已经存在,则清除文件内容,指针定位在文件开头 |
w+ | 读写模式,如果文件不存在,则创建文件;如果文件已经存在,则清除文件内容,指针定位在文件开头 |
a | 追加模式,如果文件不存在,则创建文件;如果文件已经存在,则在文件末尾追加内容,指针定位在文件末尾 |
a+ | 追加模式,如果文件不存在,则创建文件;如果文件已经存在,则在文件末尾追加内容,读指针定位在文件开头,写指针定位在文件末尾, |
fopen函数的使用>>
FILE* fp = NULL;
fp = fopen("./file01.txt","w");//第一个参数为文件的路径,第二个参数为文件的打开方式
//如果改路径下没有改文件则创建文件
/*不同的打开方式*/
//fp = fopen("./file01.txt","w+");
//fp = fopen("./file01.txt","r");
//fp = fopen("./file01.txt","r+");
//fp = fopen("./file01.txt","a");
//fp = fopen("./file01.txt","a+");
if(fp == NULL)
{//如果是读文件,如果文件不存在
printf("Couldn't open file\r\n");
return -1;
}
printf("file : %p\r\n",fp);
执行后可以看到文件夹下多创建了一个file01.txt文件
头文件 :<stdio.h>
函数原型 :int fclose(FILE *stream);
函数功能 :关闭给定指针指向的文件
参数1 :要关闭的文件指针
返回值 :成功返回0。失败返回-1,并置位错误码
===========================================
FILE* fp = NULL;
fp = fopen("./file01.txt","r");//打开文件
if(fp == NULL)
{
printf("Couldn't open file\r\n");
return -1;
}
printf("file : %p\r\n",fp);
if(fclose(fp)==0)//判断关闭文件是否关闭成功
{
printf("close file\r\n");
}else if(fclose(fp)==-1)
{
printf("Couldn't close file\r\n");
}
错误码:
在文件I0或标准I0相关接口被调用是,如果出错了,操作系统会给应用程序返回一个错误码,一共有4096个,每一个代表不同的错误,错误码返回的是负数如下是部分错误码
errno为头文件以定义的全局变量,可以直接使用无需定义
错误码头文件 :#include <errno.h>
函数 :strerror(errno);
输入错误码
输出错误码对于的错误信息
=======================================================================
fp = fopen("./file02.txt","r");//该路径下没有此文件,并且以只读模式打开
if(fp == NULL)//因为打开失败更新了错误码
{
printf("%s\r\n",strerror(errno));//打印错误码对应的错误
return -1;
}
输出>>
No such file or directory
=======================================================================
函数 :perror(const* p);
输入信息
如:
perror("open file");
当错误码更新时,该函数执行效果>>
open file: No such file or directory
函数原型 :int fputc(int c,FILE*stream);
功能 :从程序中向指定文件中输出一个字符/向文件在中输入一个字符
输入参数1 :被输出字符的ASCII码值/被写入文件字符的ASCII码值
输入参数2 :指定文件指针
返回值 :成功返回ascii值,失败返回EOF/-1
===========================================================
FILE* fp = NULL;
if((fp=fopen("./file01.txt","w")) == NULL)
{//判断文件是否打开成功
perror("open file");
return -1;
}
fputc('h',fp);//向指定文件内输入单个字符
fputc('e',fp);
fputc('l',fp);
fputc('l',fp);
fputc('o',fp);
fputc('\n',fp);
fclose(fp);
运行完成后使用cat命令在终端查看被写入的文件
>>cat file01.txt
终端输出>>可以看到文件内已经写入了hello
hello
函数原型 :int fgetc(FILE *stream);
功能 :从指定文件中读取一个字符到程序
输入参数1 :指定的文件指针
返回值 :成功返回ascii值,读取失败或文件结束返回EOF/-1
===========================================================
文件file01.txt内已保存字符串hello带换行
char ch = 0;
FILE* fp = NULL;
if((fp=fopen("./file01.txt","r")) == NULL)
{//判断文件是否打开成功
perror("open file");
return -1;
}
while ((ch=fgetc(fp)) != EOF)//直到文件读取失败或文件结束
{//循环读取文件中的字符并赋值输出
printf("%c",ch);
}
stdout
stdout是一个Linux系统中的标准输出流,它指向屏幕或是其他输出设备。我们可以使用各种编程语言和命令行工具来将输出写入stdout,如echo命令。在Linux中,stdout有一个文件描述符(file descriptor)为1。
stdin
stdin代表标准输入流,是Linux系统中的一个预定义文件流。在Linux系统中,程序可以从stdin读取输入数据。stdin通常用于从终端(例如键盘)读取输入数据。当用户在终端上输入一些数据时,它们会被发送到stdin流中,程序可以从stdin中读取这些数据。
stderr
tderr是Linux中的一个特殊文件描述符,它代表标准错误流(Standard Error)。它用于将程序中产生的错误信息输出到屏幕或日志文件中。通常,若程序执行成功,其标准错误流不会有任何输出。当程序发生错误时,其标准错误流将输出相应的错误信息。
函数原型 :int fputs(const char *s, FILE *stream);
功能 :将指定的字符串s,写入到给定的文件中
输入参数1 :要写入的文件字符串
输入参数1 :文件指针
返回值 :成功返回成功写入字符的个数(非负整数),读取失败或文件结束返回EOF/-1
===========================================================
FILE* fp1 = NULL;
if((fp1=fopen("./file01.txt","w")) == NULL)
{
perror("open file");
return -1;
}
fputs("asd\r\n",fp1);
fclose(fp1);
运行完成后使用cat命令在终端查看被写入的文件
>>cat file01.txt
终端输出>>可以看到文件内已经写入了asd
asd
===========================================================
fputs("asd\r\n",stdout);
函数原型 :char *fgets(char*s. int size. FILE *stream);
功能 :从给定的文件stream中,读取至少小于size个字符,放入到给定字符数组s中
遇到换行或者EOF停止读取,换行符号也会被读取到s中,在全部读取结束后,会自定加一个"\0"
输入参数1 :要存放数据的字符数组
输入参数2 :读取的大小(读取的字符串实际长度为size-1)
输入参数3 :文件指针
返回值 :成功返回s数组,失败返回NULL
===========================================================
char str1_buff[255] = {0};
//从终端获取字符串
fgets(str1_buff, sizeof(str1_buff), stdin);
printf("%s",str1_buff);
1. 全缓存:跟自定义文件指针有关的缓冲区,其大小为4096字节
2. 行缓存:跟终端相关的操作使用的是行缓存(stdin、stdout),其大小为1024字节
3. 不缓存:跟标准出错有关的操作是不缓存(stde),其大小为0
int i = 0;
FILE* fp1 = NULL;
if((fp1=fopen("./file01.txt","w")) == NULL)
{
perror("open file");
return -1;
}
printf("\r\n");
scanf("%d",&i);//输入任意值
printf("stdin行缓存:%ld\r\n",stdin->_IO_buf_end - stdin->_IO_buf_base);
printf("stdout行缓存:%ld\r\n",stdout->_IO_buf_end - stdout->_IO_buf_base);
printf("不缓存:%ld\r\n",stderr->_IO_buf_end - stderr->_IO_buf_base);
printf("文件全缓存:%ld\r\n",fp1->_IO_buf_end - fp1->_IO_buf_base);
输出>>
stdin行缓存:1024
stdout行缓存:1024
不缓存:0
文件全缓存:4096
- 遇到‘\n’会刷新行缓存
printf("hello\n"); while(1)
- 程序结束后会刷新行缓存
printf("hello");
- 当缓冲区进行切换时也会刷新缓存区
printf("hello"); int n; scanf("%d",&n); while(1);
- 当关闭文件指针时,也会刷新行缓存
printf("hello world"); fclose(stdout);//关闭文件指针 while(1);
- 手动刷新缓存区时,行缓存会进行刷新
printf("hello world"); fflush(stdout);//手动刷新缓存区 while(1);
- 当缓存区满了后,会自动刷新缓存区
for(int i=0; i<1025; i++) { printf("%c","a'); } while(1);
- 全缓存遇到’\n’
不会
刷新缓冲区- 程序结束后会刷新行缓存
- 当输入输出缓冲区发送切换时会刷新
fputc('A',fp); fgetc(fp); while(1);
- 当关闭文件时,会刷新全缓存
fputc('A',fp); fclose(fp); while(1);
- 手动刷新缓存区时,行缓存会进行刷新
- 当缓存区满了后,会自动刷新缓存区
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
int cnt = 0;
char ch = 0;
char str_buff[255] = {0};
FILE* fp1 = NULL;
if((fp1=fopen("./file01.txt","r")) == NULL)
{
perror("open file");
return -1;
}
while(fgets(str_buff,3,fp1) != NULL)
{
if(str_buff[strlen(str_buff)-1] == '\n') cnt++;
}
fclose(fp1);
printf("行数为 %d\r\n",cnt);
return 0;
}
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
int cnt = 0;
char ch = 0;
char str_buff[255] = {0};
FILE* fp1 = NULL;
FILE* fp2 = NULL;
if((fp1=fopen("./file01.txt","r")) == NULL)
{//打开要被拷贝的文件
perror("open file");
return -1;
}
if((fp2=fopen("./file02.txt","w")) == NULL)
{//打开拷贝文件
perror("open file");
return -1;
}
while(fgets(str_buff,3,fp1) != NULL)
{
fputs(str_buff,fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}