目录
1.标准io; stdio.h
1.1标准io的概念
1.2Linux操作系统当中IO都是对文件的操作
1.3标准IO:ANSI C 设计的一组用文件IO 封装的操作库函数
2.文件
2.1作用
2.2linux中文件的类型
3.man
5.流: FILE*
5.1流的定义
5.2流的分类
6.c语言文件读写操作函数
6.1操作步骤
6.2函数
6.2.1打开
fopen
6.2.2读写操作相关
1)fputc
2)fgetc
3)fputs
4)fgets
注意:
5)fwrite(二进制)
6) fread(二进制)
6.2.3关闭
fclose
7.缓冲
7.1行缓冲
7.1.1大小
7.1.2操作位置
7.1.3刷新条件
7.1.4操作指令
7.2全缓冲
7.2.1大小
7.2.2作用
7.2.3刷新条件
7.3无缓冲
7.3.1大小
7.3.2作用
7.3.3不对数据缓存直接刷新
8.标准IO之文件定位
8.1fseek
8.2ftell
8.3rewind
1.标准io; stdio.h
1.1标准io的概念
1975 Dennis r IO库,C语言的标准,ANSI c
IO input output
I: 键盘是标准输入设备 ====》默认输入就是指键盘 /dev/input
O: 显示器是标准输出设备 ==》默认输出就是指显示器
1.2Linux操作系统当中IO都是对文件的操作
C一部分,任何支持标准C的系统都可使用标准IO实现文件存储
标准IO在UNIX上是对文件IO的封装
一般都是对普通文件操作是一种有缓存的IO 在文件IO和用户程序之间,加入缓冲区,可以有效减少系统调用的效率,节省系统IO调度资源
1.3标准IO:ANSI C 设计的一组用文件IO 封装的操作库函数
头文件: stdio.h ==》标准输入输出头文件
/usr/include/stdio.h
<> 是系统库函数,默认路径在/usr/include/
eg : ====》stdio.h ===>stdio.c==>libc.so ==>/usr/lib so 动态库
"" 是用户自定义函数,默认是当前路径
eg : ===>xxx.h ===>xxx.c
2.文件
2.1作用
linux中一切都是文件。文件用来存储数据(数据,指令);
2.2linux中文件的类型
7种,d ,-,l,p管道,s,c,b 用命令演示 link pip socket
hello oellh,,512
io的分类
标准io,
stdio.h
Dennis Ritchie
3.man
man ==>所有man的帮助
man xxx == man 1 xxx ===>查看当前xxx命令
man 2 xxx ===>查看xxx对应的系统调用函数
man 3 xxx ===》查看xxx对应的标准库函数
注意:如果没有命令则直接man xxx 会显示其函数\n
如果没有系统调用则显示系统库函数帮助
printf scanf
sprintf
getchar putchar gets puts\n
getc putc fgets fputs fread fwrite ftell
rewind fseek
文件io,系统调用,底层软件
文件内容的分类, 文本文件,二进制文件
5.流: FILE*
struct FILE
{
}
5.1流的定义
数据从文件当中流入和流出所体现出来的字节流叫做流
5.2流的分类
1)二进制流: 2001 \n
2)二进制数据的流
3)文本流:
4)ASCII码数据的流 \n \t
5)FILE 结构定义的对象 FILE * 称之为流对象,也叫文件流指针。
流对象 ===》头 《===数据====》尾
stdin FILE* scanf ();
stdout printf();
stderr
6.c语言文件读写操作函数
6.1操作步骤
1)打开文件 FILE
2)io操作,读写操作
3)关闭文件
6.2函数
6.2.1打开
fopen
“r”---只读 文件必须存在
“w”---创建文件,若文件存在则清空
“r+”---文件存在,进行读写
“w+”---创建一个用于读写的空文件
“a”---文件不存在则创建,追加 找到文件的末尾
“a+”---找到文件末尾读写
#include<stdio.h>int main(int argc,char *argv[])
{FILE*fp=fopen("1.txt","w");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}return 0;
}
6.2.2读写操作相关
fgetc/fputc,,,,,,一个字符
1)fputc
int fputc(int C,FILE *stream);
功能:向指定的文件流写入单个字符数据。
特点:每次只写入一个字符。
#include<stdio.h>int main(int argc,char *argv[])
{//1 open file//2 read write// close file// 打开,如果文件不存在,创建文件,// 如果存在,清空文件内容 wFILE*fp=fopen("1.txt","w");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}fputc('h',fp);fputc('e',fp);fputc('l',fp);fputc('l',fp);fputc('o',fp);fclose(fp);
}
fgetc(int c ,FILE*strem);
2)fgetc
int fgetc(FILE *stream);
功能: 从指定的文件流中逐个字符地读取数据。
特点: 每次只读取一个字符,并随着每次调用向前移动文件指针。返回值类型为 int,以容纳 EOF 的负数值。
#include<stdio.h>int main(int argc,char*argv[])
{FILE*fp=fopen("1.txt","r");if(NULL==fp){fprintf(stderr,"open error\n");return 1;}while(1){int c=fgetc(fp);if(EOF==c){break;}printf("%c",c);}return 0;
}
fgets/fputs....,,一次一行
3)fputs
int fputs(const char *s,FILE *stream);
功能:向指定的文件流写入字符串数据。
特点:将整个字符串一次性写入文件。不会在字符串末尾自动添加换行符,如果需要换行,应在字符串中显式添加。
#include <stdio.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "w"); //清空 创建if(NULL==fp){printf("fopen error\n");return 1;}//文本文件的写fputs("hello\n",fp); //常量char buf[]="world";fputs(buf, fp); //变量fclose(fp);// system("pause");return 0;
}
4)fgets
char *fgets(char *s, int size, FILE *stream);
功能:从指定的文件流中读取一行字符串,并将其存储到指定的字符数组中。
特点:会一次性读取一整行,包括换行符(‘\n’),并将其存储到目标数组中。可以指定最大读取的字符数,以防止缓冲区溢出。
#include <stdio.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r"); //文件已存在if(NULL==fp){printf("fopen error\n");return 1;} char buf[512]={0};while(1){char *tmp=fgets(buf, sizeof(buf), fp);if(NULL==tmp) //到文件的结尾{break;}printf("%s",buf);}fclose(fp);// system("pause");return 0;
}
注意:
1)fputs和fgets只处理文本文件不处理二进制文件
2)od -c 文件
eg:od -c 1.txt ----查看1.txt具体内容
3)od -t x1 1.png | less
----用十六进制查看1.png具体数值
4)hexdump 1.png -C |less
-----十六进制转储显示并显示ascii码
5)vimdiff -----比较两个文件差异
eg: vimdiff /ect/passwd 1.txt 比较passwd和1.txt的差异
5)fwrite(二进制)
size_t fwrite(const void *ptr,size_t size, size_t nmemb, FILE *Stream);
自定义大小
#include <stdio.h>
#include <string.h>typedef struct {int id;char name[50];char addr[100];}PER;int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "w");if(NULL==fp){printf("fopen error\n");return 1;}PER per;bzero(&per, sizeof(per));per.id=10;strcpy(per.name, "zhangsan");strcpy(per.addr, "成都");size_t ret=fwrite(&per, sizeof(per), 1, fp); printf("write num of item:%lu\n",ret);fclose(fp);return 0;// system("pause");return 0;
}
6) fread(二进制)
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
struct person
{
char name[10];
int age;
char phone[15];
};
person son[10];
#include <stdio.h>
#include <string.h>typedef struct {int id;char name[50];char addr[100];}PER;int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){printf("fopen error\n");return 1;}PER per;bzero(&per,sizeof(per));size_t ret=fread(&per, sizeof(per), 1, fp);printf("ret:%lu id:%d name:%s addr:%s\n",ret,per.id,per.name,per.addr);fclose(fp);// system("pause");return 0;
}
注意:
atoi----将字符转换为数字
6.2.3关闭
fclose
7.缓冲
产生原因:内存和屏幕有快有慢
7.1行缓冲
7.1.1大小
1k -----1024
7.1.2操作位置
terminal,主要用于人机交互stdout
行缓存多是关于终端的一些操作
缓存区满或者遇到\n刷新
7.1.3刷新条件
1.遇到\n刷新
2.缓存区满刷新
3.程序结束刷新
4.fflush刷新 fflush(stdout);
7.1.4操作指令
FILE*fp
标准输入(键盘)stdin
标注输出(屏幕)stdout
标准错误输出(屏幕)stderr
#include <stdio.h>
// #include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv)
{
// 情况1// printf("hello");// while(1);//情况2 缓存大小是 1024 字节
// int i = 0;
// for (i = 0; i < 1024; i++)
// {
// fputc('a', stdout); // FILE* 标准输入(键盘)stdin 标准输出(屏幕) stdout
// // 标准错误输出(屏幕) stderr
// }
// sleep(5);
// fputc('a', stdout);
// while (1);//情况3 程序正常结束//printf("hello");//情况4 强制刷新缓冲区printf("hello");fflush(stdout);while(1);return 0;
}
7.2全缓冲
7.2.1大小
4k---4096
7.2.2作用
主要用于文件的读写
缓存区满刷新缓存区
对普通文件进行标准IO操作,建立的缓存一般为全缓存
7.2.3刷新条件
1.缓存区满刷新
2.程序正常结束刷新
3.fflush来刷新 fflush(fp);
#include <stdio.h>
// #include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv)
{// 1// FILE* fp = fopen("1.txt","w");// fputs("hello",fp);// while(1);// 2 4K// FILE* fp = fopen("1.txt", "w");// int i = 0;// for (i = 0; i < 4096; i++)// {// fputc('a', fp);// }// sleep(10);// fputc('a', fp);// while (1);// 3 fflush();FILE* fp = fopen("1.txt", "w");fputs("hello", fp);fflush(fp);while (1);return 0;
}
7.3无缓冲
7.3.1大小
0k ----0
7.3.2作用
主要用于出错处理信息的输出 stderr
7.3.3不对数据缓存直接刷新
printf( );==>>stdout
fprintf(strerr,"fopen error %s",filename);
界面交互 出错处理
使用gdb查看,FILE结构体,或使用写入数据测试缓冲区。
缓冲区的大小是可以设置
8.标准IO之文件定位
fseek ftell rewind
8.1fseek
int fseek(FILE *stream, long offset, int whlence);
功能:将stream流文件中的文件指针从whence位置开始 偏移offset字节的长度。
参数:
stream要移动文件指针的目标文件流对象。
注意:不支持设备文件,一般用于普通文件。
offsett要在文件内偏移的距离,单位字节。
如果值为整数,则向文件末尾偏移
如果值为负数,则向文件开头偏移
whence 偏移的起始位置,由系统定义的三个宏开始。
SEEK_SET 文件的开头位置
SEEK_CUR文件的当前位置
SEEK_END文件的末尾位置
返回值:
成功:返回0
失败:-1;
如果从文件的指定位置向后偏移过程中已经超过了文件 的当前末尾位置,则会自动以\0'来填充文件内容,从 而形成一种被称为"空洞文件"的特殊文件。
#include<stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt","r");if(NULL==fp){fprintf(stderr,"fopen error\n");return 1;}fseek(fp,27,SEEK_SET);char buf[50]={0};fgets(buf,sizeof(buf), fp);fclose(fp);printf("buf:%s\n",buf);// system("pause");return 0;
}
8.2ftell
long ftell(FILE *stream);
功能:
获得文件大小。
返回文件指针相对于起始位置的偏移量。
参数:
stream要移动文件指针的目标文件流对象。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){fprintf(stderr, "fopen error\n");}fseek(fp, 0,SEEK_END);long size=ftell(fp);printf("size:%ld\n",size);fclose(fp);// system("pause");return 0;
}
8.3rewind
void rewind(FILE *stream);
功能:
让文件流指针回到文件开头(直接复位到开头)。
rewind(fp);=====fseek(fp,0,SEET_SET); 二者等价
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main(int argc, char **argv)
{FILE*fp=fopen("1.txt", "r");if(NULL==fp){fprintf(stderr, "fopen error\n");return 1;}fseek(fp, 0, SEEK_END);//文件到达结尾long size=ftell(fp);printf("size:%ld\n",size);char buf[512]={0};rewind(fp);//文件在开头---pos==0的位置fgets(buf, sizeof(buf), fp);printf("%s\n",buf);fclose(fp);// system("pause");return 0;
}