应用层
1.标准IO库的所有操作都是围绕流(strem)来实现的;
FILE * 流指针,文件指针
2./dev 目录下
stderr 2 //标准出错文件
stdout 1 //标准输出文件
stdin 0 //标准输入文件
stdio.h
#include
int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);//把字符输出到流
例如:
fprintf(stdout,"hello world\n");
fprintf(stderr,"hello world\n"):
fprintf(stdout,"a=%d\n",a);//带参数
int dprintf(int fd, const char *format, ...);
int sprintf(char *str, const char *format, ...);//向字符串中写入,
例:
sprintf(buf,"hello world %f\n",3.14);
int snprintf(char *str, size_t size, const char *format, ...);
#include
int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vdprintf(int fd, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
//返回值
成功返回后,这些函数返回打印的字符数(不包括用于结束输出到字符串的空字节)。
输出错误,则返回负值
int fclose(FILE *stream);
//返回值
RETURN VALUE
Upon successful completion 0 is returned. Otherwise, EOF is returned and errno is
set to indicate the error. In either case any further access (including another call
to fclose()) to the stream results in undefined behavior.
成功完成后返回O。否则,将返回EOF并设置errno以指示错误。在这两种情况下,对流的任何进一步访问(包括对fclose()的另一个调用)都会导致未定义的行为。
关闭输出流,则无法输出
fclose(stdout);
fprintf(stdout,"hello world\n");//
scanf();函数在缓冲区读取字符,当输入字符最后一个回车键(\n)没有输入,依然保存在缓冲区,需要使用getchar();取走回车键的字符,不然会在下一次输入时,上次留下的回车键读入。
解决这个问题,在多个scanf()函数中间添加getchar();
(1)在内存空间中预留了一定的存储空间,这用来缓冲输入或输出的数据。
FILE *fp=stdin;//大小为1024字节
char a=getchar();//需要设置输入
fp->IO_buf_end //输入缓冲区尾部指针
fp->IO_buf_base //输入患处区头部指针
(2)缓冲区的分类
1)全缓存[4096字节],输入输出是对文件操作;
./a.out >log.txt//当输出的字符少于4096时,无法输出,大于该值则输出
2)行缓存【1024字节】,输入输出是对屏幕操作;
特点:
遇到\n会刷新,缓冲满了会刷新,程序正常结束会刷新【调用exit或从main函数返回】
调用fflush()会强制刷新缓存;遇到\n会刷新缓存。
main()
{
for(i=1;i<=200;i++)
{
printf("A");
}
while(1);
}
//执行该程序,未能在输出栏看到输出数据,以为输出的内容在缓冲区,并且未达到刷新缓冲区的要求,所以看不到,当设置i<1024时就可以输出,或者最后输出地方添加\n,fflush()函数。
fflush(stdout);
或者使用 putchuar('\n');
int main(int argc,const char * argv[])
{
}
argc :输入参数的个数
argv[]: 输入参数的数组
argv[0] :执行文件的名字
argv[1] :执行文件 后第一参数
FILE *fopen(const char *path,const char *mode);
//返回值为一个文件指针,
返回NULL则表示打开出错
//const char *path 文件地址,是一个字符串
//const char *mode 打开文件的方式
打开文件方式
"r" :只读打开,不能修改文件
"r+" :读写方式打开,没有文件报错
"w" :只写打开,没有文件创造文件,有内容则清空重写
"w+" :读写打开,没有文件创造文件,有内容则清空重写;
"a" :追加方式打开,没有文件创造文件;
"a+" :追加读写方式打开,没有文件创造文件,读从文件开头开始读,写从文件结尾的位置写
vim -t EIO //查看错误码
errno //全局错误码使用errno.h
man 3 perror
打印错误码
printf("%d",errno);
perror("Fail to open");自动把系统错误打印在后面
自动添加 :错误信息
打印错误信息
printf("%s",strerror(errno));//函数内传入错误码,打印错误信息
使用标准IO把字符写入文件(1)
#include
#include
#include
int main(int argc,const char* argv[])
{
FILE *fp=NULL;
if(artc!=2)
{
fprintf(stderr,"usage: %s log.txt\n",argv[0]);//如果没有给文件名,则报错
return -1;
}
//读写打开
fp=fopen(argv[1],"r+);
if(NULL==fp)
{
fprintf(stderr,"Fail to fopen %s\n",strerror(errno));
return -1;
}
fprintf(fp,"hello world!\n");//把字符串写入文件指针中
//关闭文件
fclose(fp);
return 0;
}
#include
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
int fgetc(FILE *stream);//从流读出字符
char *fgets(char *s, int size, FILE *stream);
int getc(FILE *stream);
int getchar(void);
int ungetc(int c, FILE *stream);
读取文件,把文件内容打印在终端。(类似cat命令)
#include
int main(int argc,const char * argv[])
{
FILE *fp=NULL;
int ch;
if(artc!=2)
{
fprintf(stderr,"usage: %s log.txt\n",argv[0]);//如果没有给文件名,则报错
return -1;
}
//读写打开
fp=fopen(argv[1],"r+");
if(NULL==fp)
{
fprintf(stderr,"Fail to fopen %s\n",strerror(errno));
return -1;
}
while(1)
{
ch=fgetc(fp);
if(ch==EOF)
{
break;
}
fputc(ch,stdout);
}
fclose(fp);
return 0;
}
从流中读取size-1个字符,写入指针s所指地址,在EOF 或者换行符后停止读取,如果读取了换行符,则将其存储到缓冲区。
返回值:成功返回s的地址,失败或者读到文件末尾返回NULL;
#include
int fgetc(FILE *stream);
char *fgets(char *s, int size, FILE *stream);//最多获取字符数比size少一个,最后要加一个\0
int getc(FILE *stream);
int getchar(void);
int ungetc(int c, FILE *stream);
#include
int fputc(int c, FILE *stream);
int fputs(const char *s, FILE *stream);
int putc(int c, FILE *stream);
int putchar(int c);
int puts(const char *s);
//示例:向文件中输入
FILE *fp=NULL;
char buf{100]={0};
fp=fopen("log.txt","w");
if(fp==NULL)
{
perror("Fail to fopen!");
return -1
}
strcpy(buf,"hello world");
int ret=fputs(buf,fp);
if(ret<0)//EOF=-1
{
perror("Fail to fputs");
return -1;
}
close(fp);
//return value:返回值
//fputc(), putc() and putchar() return the character written as an unsigned char cast to an int or EOF on error. EOF 在 /usr/include/stdio.h 宏定义为-1
// puts() and fputs() return a nonnegative number on success, or EOF on error.
#include
#include
#include
int main(int argc,const char *argv[])
{
char buf[120]={0};
while(1)
{
bzero(buf,sizeof(buf));
putchar('>');
fgets(buf,sizeof(buf),stdin);
if(strncmp(buf,"quit",4)==0)
{
break;
}
fputs(buf,stdout);
}
return 0;
}
//
#include
int getLine(FILE *fp)
{
char buf[1024]={0};
int line=0;
while(fgets(buf,sizeof(buf),fp)!=NULL)//当没有读到文件尾部的时候,继续读
{
if(buf[strlen(buf)-1]=='\n')
{
line++;
}
memset(buf,0,sizeof(buf));
}
return line;
}
int main(int argc,const char *argv[])
{
FILE *fp;
int line=0;
if(argc!=2)
{
perror(stderr,"Usage: %s log.txt",argv[0]);
return -1;
}
fp=fopen(argv[1],"r");
if(NULL==fp)
{
perror("Fail to fopen");
return -1;
}
line=getLine(fp);
printf("%s:%d\n",argv[1],line);
fclose();
return 0;
}
//返回值:成功返回读取的个数
//示例:把结构体写入文件[od -c 文件名 //可以查看文件的结构]
#include
struct student
{
char name[20];
int id;
int score;
};
int main(int argc,const char *argv[])
{
FILE *fp;
struct student stu={"jack",1,100);//给结构体赋值
if(argc!=2)
{
perror(stderr,"Usage: %s log.txt",argv[0]);
return -1;
}
fp=fopen(argv[1],"w");
if(fp==NULL)
{
perror("Fail to fopen");
return -1;
}
fwrite(&stu,sizeof(stu),1,fp);//1是写入数据的个数
fclose(fp);
return 0;
}
//参数:whence 光标相对偏移起点:SEEK_SET 以文件开头为起点;SEEK_CUR 当前位置为偏移起点;SEEK_END 文件结尾为偏移起点;
//参数:offset >0 则向后偏移,<0 向前偏移
//返回值:成功返回0,失败返回-1,置errno
#include
int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);//返回当前光标的位置
void rewind(FILE *stream);//将光标定位到文件开头
int fgetpos(FILE *stream, fpos_t *pos);
int fsetpos(FILE *stream, const fpos_t *pos);
//示例:移动文件光标//文件开头为0
fseek(fp,4,SEEK_SET);//定位到文件开头往后数4bytes的位置
fseek(fp,-4,SEEK_END);//定位到文件末尾往前数4bytes的位置
fseek(fp,10,SEEK_END);//将文件的大小扩充10bytes
把光标定位到开头
fseek(fp,0,SEEK_SET);//和rewind 等价
rewind(fp);//该函数和上个函数等价