目录
2,读文件:read 从打开的⽂件中读取⽂件内容,然后输⼊到程序中去。
3,写入文件:write从程序中把内存数据写⼊到⽂件中,程序输出到⽂件中。
3.1,复制整个字符串内容粘贴到这个字符串,覆盖原字符串中所有的内容
3.2, 复制字符串中前n个字符串内容粘贴到原字符串,原字符串中的全部内容都会被覆盖。
IO文件系统
名词解释:
io:即input,output,文件的读写。
一,多文件编程
即用一个程序源代码把具有相同功能的程序添加在这个文件中,这就叫多文件编程。
编译机制:
① 预处理:gcc -E 文件名.c -o 文件名.i
② 编译:gcc -s 文件名.i -o 文件名.s
③ 汇编:gcc -C文件名.s -o 文件名.o
④ 链接:gcc 文件名.O
头文件:用于多文件书写时的声明。
头文件的格式:#include<xxx.h>或者#include"xxx.h"。注:""表示其他路径,<>表示当前路径的声明。
注:虽然是多文件编程但是在链接前各个步骤都是分别进行的,只是在运行程序时进行链接。
预处理命令:在编译过程中,在预处理阶段执行某一段操作,不执行其他段的代码。
格式 #if
#else
..............
#endif
宏定义:用当前的值代替其他的值区别于类型替换(typedef)
格式:#define n 10,即用n代表10。
注:宏定义同样只能执行替换一个语句,(即执行一个分号之前的语句)如果要同时使用多个语句可以使用do while语句或者把多个语句通过添加{ };进行更改。
do while 语句:第一次条件不做判断,从第二次开始执行判断。
格式:do
{
}while();
二,文件IO
程序操作磁盘上的文件就是对文件的读写操作
读:将磁盘中的文件放入到程序中来——>输入
写:将程序中的文件存放在磁盘中去——>输出
文件的操作
函数名含义的查看:man +函数名。
1, 文件的打开:open
1.1, 只打开文件
//要使用open 这个函数就必须对其声明。
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
//打开⽂件
int open(const char *pathname, int flags);
/*
参数1:
const char *pathname:字符指针,表⽰的是字符的地址,字符串的⾸地址,要打开的⽂件路径字符串的地址.
const:表示指向的指针地址可以进行修改。
参数2:
int flags:整数,打开⽂件的选项
O_RDONLY:只读
O_WRONLY:只写
O_RDWR:读写
O_TRUNC:清空⽂件(在有 写 ⽅式 有效)
O_APPEND:追加⽂件(在有 写 ⽅式 有效),在写⽂件时,在⽂件末尾位置添加写
O_CREAT:如果⽂件不存在则,创建⽂件,存在则直接打开。
返回值:
成功返回>=0
失败返回-1
*/
1. 2,创建且打开文件
int open(const char *pathname, int flags, mode_t mode);
2,读文件:read 从打开的⽂件中读取⽂件内容,然后输⼊到程序中去。
//文件声明
#include <unistd.h>
//格式:
ssize_t read(int fd, void *buf, size_t count);
/*
从指定的fd(打开的⽂件中,读取count个字节数据,存放到程序的内存buf地址开始位置)
参数1:
int fd:⽂件描述符,表⽰打开的⽂件
参数2:
void *buf:指针,表⽰把从⽂件中读取的内容,存放到程序指定的内存地址中
参数3:
size_t count:整数,表⽰从⽂件中读取多少个字节的数据内容
返回值:
成功:返回读取到的字节数,如果返回值为0表⽰本次读取是从⽂件末尾开始读取,没有内容
失败:-1
*/
3,写入文件:write从程序中把内存数据写⼊到⽂件中,程序输出到⽂件中。
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
/*
把buf这个内存地址的中的数据,拿出 count字节数,写⼊到fd⽂件中。
参数1:
int fd:要写⼊哪个⽂件
参数2:
const void *buf:要写⼊的内容在哪个内存地址(把哪个内存地址的内容,写⼊⽂件)
参数3:
size_t count:要写⼊内容的⼤⼩
返回值:
成功:返回写⼊的字节数
失败:返回-1
*/
4,关闭文件:close把打开的⽂件关闭
#include <unistd.h>
int close(int fd);
/*
参数1:
int fd:⽂件描述符,表⽰关闭哪个打开的⽂件
返回值:
成功:返回0
失败:返回-1
*/
注:对于程序⽽⾔,系统默认打开了终端⽂件 终端⽂件打开了三次,分别以不同的⽅式打开。
⽂件描述符如下:
0:读打开,只读,可以读取终端⽂件内容(命令⾏输⼊的内容)
1:写打开,只写,可以写⼊到终端⽂件(终端上显⽰)
2:写打开,只写,以更⾼权限写,程序出错时,想⽴即显⽰
5,设置文件偏移位置:lseek
#include <sys/types.h>
#include <unistd.h>
//重新设置⽂件当前操作位置(修改偏移位置)
off_t lseek(int fd, off_t offset, int whence);//设置打开的fd⽂件的偏移位置
/*
参数1:
int fd:表⽰打开的⽂件,需要被设置偏移量的⽂件
参数2:
off_t offset:整数,偏移量,表⽰偏移多少个字节
+:正数,向⽂件末尾靠近偏移
-:负数,向⽂件开头靠近偏移
参数3:
int whence:基准点,表⽰从哪个位置开始计算如下
SEEK_SET:从⽂件开始位置计算偏移
SEEK_CUR:从⽂件当前的操作位置计算偏移
SEEK_END:从⽂件末尾位置开始计算偏移
返回值:
成功:返回从⽂件开始位置到新偏移之后位置⼀共多少个字节
失败:返回-1
*/
注:位置偏移可以超过当前⽂件⼤⼩,超过的文件大小的文件叫做空洞⽂件,中间空洞部分每个字节都 会补'\0'
三,目录操作
1,创建目录文件
命令:mkdir 在指定⽬录中创建⼀个⽬录⽂件
//头文件
#include <sys/stat.h>
#include <sys/types.h>
//格式:
int mkdir(const char *pathname, mode_t mode);
/*
参数1:
const char *pathname:指针,字符串⾸地址,要创建的⽬录⽂件的路径
参数2:
mode_t mode:创建的⽬录的权限(读写执⾏)
返回值:
成功:返回0
失败:返回-1
*/
举例说明:
2,删除目录文件
命令:rmdir 删除指定位置的文件目录
//头文件
#include <unistd.h>
//格式
int rmdir(const char *pathname);
/*
参数:
const char *pathname:字符串⾸地址,表⽰要删除的⽬录
返回值:
成功:返回0
失败:返回-1
*/
举例说明:
3,打开目录文件
去打开对应路径下的⽬录
//头文件
#include <sys/types.h>
#include <dirent.h>
//格式
DIR *opendir(const char *name);
//DIR:⽬录信息结构体类型
/*
参数:
const char *name:字符串⾸地址,表⽰要打开的⽬录⽂件路径
返回值:
成功:返回⽬录信息结构体的地址(指针),标识打开的⽬录⽂件
失败:返回NULL(空指针)
*/
举例说明:
获取已经打开的文件 :readdir
#include <dirent.h>
struct dirent * readdir(DIR *dirp); //获取打开的⽬录中,⼀个⽂件
/*
参数1:
DIR *dirp:获取哪个(打开的)⽬录中的⽂件
返回值:
成功:返回获取到的这个⽂件的描述(结构体)的地址
NULL:表⽰本次获取已经获取到⽬录的结尾了没有⽂件了(已经获取完)
*/
//⽂件描述结构体
struct dirent
{
ino_t d_ino; //inode号,⽂件系统中对⽂件的唯⼀编号
off_t d_off; //偏移
unsigned short d_reclen; //⻓度⼤⼩
unsigned char d_type; //⽂件类型
char d_name[256]; //⽂件名
};
举例说明:
4,关闭目录文件
关闭已经打卡的目录文件:closedir
#include <sys/types.h>
#include <dirent.h>
int closedir(DIR *dirp);
/*
参数:
DIR *dirp:表⽰要关闭的⽬录⽂件
返回值:
成功:返回0
失败:返回-1
*/
四,字符串的操作
1,字符串的比较
1.1,比较全部字符串
比较两个字符串 从第⼀个字符内容开始⽐较,⼀直⽐ 较到字符串结束,如果每个字符内容都相等,则整个字符串相等,返回0,否则返回负数。
int strcmp(const char *s1, const char *s2);
1.2,比较前n个字符串
⽐较两个字符串中的前n个字符内容是否相等,相等返回0 ,否则返回负数。
int strncmp(const char *s1, const char *s2, size_t n);
举例说明:
2,字符串的追加
2.1,将整个字符串内容添加到该字符串最前位置
char *strcat(char *dest, const char *src);
举例说明:
2.2,将这个字符串中的前n个字符内容串添加到该字符串
char *strncat(char *dest, const char *src, size_t n);
举例说明:
3,字符串的拷贝
3.1,复制整个字符串内容粘贴到这个字符串,覆盖原字符串中所有的内容
char *strcpy(char *dest, const char *src);
举例说明:
3.2, 复制字符串中前n个字符串内容粘贴到原字符串,原字符串中的全部内容都会被覆盖。
char *strncpy(char *dest, const char *src, size_t n);
举例说明:
4,字符串的长度
计算整个字符串的长度,不会计算“\0”,返回的就是字符串的长度。
size_t strlen(const char *s);
举例说明:
五,标准IO
库函数:存放在函数库中的函数。库函数具有明确的功能、入口调用参数和返回值。 由计算机语⾔标准委员会审核通过。
系统调用:内核提供给应用程序使用的功能函数,它只能在对应平台使用。
标准IO:标准I/O是ANSI C建立的一个标准I/O模型,是一个标准函数包和stdio.h头文件中的定义,具有一定的可移植性。标准IO库处理很多细节。例如缓存分配,以优化长度执行IO等。标准的IO提供了三种类型的缓存(全缓存,行缓存,无缓存)。
1,文件的打开:fopen
打开指定的⽂件
#include <stdio.h>
FILE *fopen(const char *pathname, const char *mode);
/*
参数1:
const char *pathname:字符串⾸地址,表⽰要打开的⽂件路径
参数2:
const char *mode:字符串⾸地址,通过通过字符串来表⽰
返回值:
FILE:是⼀个结构体,描述打开的⽂件信息(包括了⽂件描述符)返回值就是返回FILE这个结构体类型变量的地址
成功:返回FILE * 指针,⽂件信息结构体地址(能知道打开
的⽂件)
失败:返回NULL(空指针)
*/
打开文件的方式 :
"r" | 只读⽅式打开(⽂件必须存在)---------O_RDONLY |
"r+" | 读写⽅式打开---------O_RDWR |
"w" | 只写⽅式打开(清空⽂件,当⽂件不存在时创建)--------- O_WRONLY | O_CREAT | O_TRUNC |
"w+" | 读写⽅式打开(清空⽂件,当⽂件不存在时创建)---- O_RDWR | O_CREAT | O_TRUNC |
"a" | 追加写⽅式打开(操作位置在⽂件末尾,当⽂件不存在时 创建)---)---------O_WRONLY | O_CREAT | O_APPEND |
"a+" | 读写⽅式打开(写为追加写操作位置在⽂件末尾,当⽂ 件不存在时创建)-----O_RDWR | O_CREAT | O_APPEND |
举例说明:
2,文件的关闭:fclose
关闭⽂件,就会把当前打开的⽂件的缓冲区存放到⽂件中
#include <stdio.h>
int fclose(FILE *stream);
/*
参数1:
FILE *stream:关闭打开的哪个⽂件
返回值:
成功:返回0
失败:返回-1(EOF)
*/
3,文件的写入:fwrite
把数据写⼊到⽂件
#include <stdio.h>
size_t fwrite(const void *ptr, size_t size, size_tnmemb,FILE *stream);
/*
参数1:
const void *ptr:要写⼊⽂件的内容对应地址
参数2:
size_t size:每⼀个数据⼤⼩
参数3:
size_t nmemb:写⼊多少个数据
参数4:
FILE *stream:写⼊的⽂件
返回值:
成功:返回写⼊的数据的个数
*/
举例说明:
4,文件的读取:fread
从⽂件中读取数据存放到ptr
#include <stdio.h>
size_t fread(void *ptr, size_t size, size_t nmemb, FILE*stream);
/*
参数1:
void *ptr:从⽂件中读取的数据存放的位置(指针)
参数2:
size_t size:每个数据⼤⼩(字节)
参数3:
size_t nmemb:读取多少个数据
参数4:
FILE *stream:读取的⽂件
返回值:
成功:返回读取的数据个数
0:表⽰读取时没有数据可读(到达⽂件末尾) , 或 读取错误。
*/
4.1,刷新缓冲区:fflush
主动把缓冲区的内容写⼊⽂件
#include <stdio.h>
int fflush(FILE *stream);
4.2,判断文件是否出错,是否读完
测试当前是否是⽂件末尾,如果是⽂件末尾返回⾮0(返回真)
#include <stdio.h>
int feof(FILE *stream);
测试当前是否是错误,如果是错误返回⾮0
#include <stdio.h>
int ferror(FILE *stream);
举例说明:
#include <stdio.h>
int main()
{
FILE * fp = fopen("home/ubuntu/homework/io/ioday2/1.txt","r");
char buf[20];
int num = 0;
while(1)
{
num = fread(buf,1,20,fp);
if(num == 0)
{
/*
if( feof(fp) )//测试是否是文件末尾
{
printf("is end of file\n");
}*/
if( ferror(fp) )//测试是否是错误
{
printf("is error\n");
}
break;
}
printf("%s\n",buf);
}
}
缓冲区的类型:
⽆缓冲:没有缓冲区,直接写⼊⽂件
⾏缓冲:当内容包含回⻋换⾏符号(\n),就会⽴即写⼊,或当缓冲区满,也会写⼊⽂件
全缓冲:当缓冲区满,才会写⼊⽂件
当系把统运⾏程序时,默认会终端⽂件打开3次:
0(终端读⽂件描述符)--------stdin(标准输⼊)-----------⾏缓冲
1(终端写⽂件描述符)--------stdout(标准输出)----------⾏缓冲
2(终端写⽂件描述符)--------stderr(标准错误输出)----⽆缓冲
5,字符的读取
5.1,单个字符的读取
从⽂件中读取⼀个字符,以返回值形式,返回读取到的字符(int)
#include <stdio.h>
int fgetc(FILE *stream);
/*
参数1:
FILE *stream:从哪个⽂件中读取
返回值:
成功:返回读取到的字符,以int类型(字符对应的ASCII码)表⽰如果本次是在⽂件末尾位置读取(⽂件结束位置),返回EOF(-1)
失败:返回EOF
需要判断 EOF到底是失败还是读取到⽂件末尾
*/
#include <stdio.h>
int main()
{
FILE * fp = fopen("/home/ubuntu/homework/io/ioday2/1.txt","w");
int c;
while(1)
{
if(c == EOF)
{
if( feof(fp) )//如果是文件末尾
{
printf("is end of file\n");
}
break;
}
}
}
int getc(FILE *stream); ==== fgetc
int getchar(void); == fgetc(stdin):从终端⽂件读取(输⼊)⼀个字符
5.2,单个字符的写入
往⽂件中写⼊⼀个字符
#include <stdio.h>
int fputc(int c, FILE *stream);
/*
参数1:
int c:要写⼊的字符的ASCII码
参数2:
FILE *stream:要写⼊的⽂件
返回值:
成功:返回写⼊的字符的ASCII码
失败:返回EOF(-1)
int putc(int c, FILE *stream); 等价于 fputc
int putchar(int c);等价于 ===== fputc(c,stdout),往终端⽂件写⼊⼀个字符。
*/
#include <stdio.h>
int main()
{
int c;
c = getchar();// ====== c = fgetc(stdin);
putchar(c);//======fputc(c,stdout);
FILE * fp = fopen("/home/ubuntu/homework/io/ioday2/1.txt","r");
FILE * fp2 = fopen("/home/ubuntu/homework/io/ioday2/2.txt","w");//写打开文件
while(1)
{
//读取1.txt文件中的字符,返回值c就是读取的字符
c = fgetc(fp);
if(c == EOF)
{
if( feof(fp) )//如果是文件末尾
{
printf("is end of file\n");
}
break;
}
//写入到2.txt文件中
fputc(c,fp2);
fflush(fp2);
}
fclose(fp);
fclose(fp2);
}
5.3,一个字符串的读取
#include <stdio.h>
char *fgets(char *s, int size, FILE *stream);
/*
从⽂件 stream中读取内容,最多读取size-1个字符,存储到s指针这个地址中。
具体读取的字符⼤⼩:⼆选⼀
1、读取到⽂件结束
2、读取到⼀⾏结束(\n)
如果在读取过程中当读取到size-1时,两个都不满⾜,则读取size-1个字符(读取最⼤⼤⼩)
注意:在读取的字符串后,加上'\0'字符,表⽰字符串的结束
返回值:
成功:返回 s 指针
NULL:本次读取在⽂件结束位置读取(已经读取到⽂件末尾)
char *gets(char *s);等价于 == fgets(s,,stdin),从终端上读取⼀个字符串,没有限制⼤⼩(没有size-1)容易越界
*/
5.4,一个字符串的写入
把s中的字符串('\0'为⽌),写⼊到⽂件中
#include <stdio.h>
int fputs(const char *s, FILE *stream);
/*
参数1:
const char *s:要写⼊的字符串,到'\0'为⽌
参数2:
FILE *stream:写⼊的⽂件
返回值:
成功:⾮负整数 >= 0
失败:EOF(-1)
int puts(const char *s);等价于 ==== fputs(s,stdout),往终端上写字符串。
*/