学习笔记,小白可以相互学习,大佬看到能告诉咱理解不对的地方就好了。
标准I/O
流(stream):所有的I/O操作仅是简单的从程序移进或者移出,这种字节流,就定义为流。
标准I/O预定义了3个流,可以自动的为进程所用
stdin 0 标准输入
stdout 1 标准输出
stderr 2 标准出错输出
标准I/O提供的3种类型缓存:
1.全缓存:当缓冲区满了或者满足一定条件才会执行刷新操作。系统是通过调用malloc来获得所需要的缓冲区域。
2.行缓存:输入、输出遇到换行符‘\n’时,进行I/O操作。典型的行缓存,当流遇到一个终端时。
3.不带缓存:标准I/O库不带字符进行缓冲,如stderr。人机交互界面不可全缓存,标准出错绝对不可全缓存。
使用setbuf()和setvbuf()可以改变缓存类型,在任何时候可以用fflush强制刷新一个数据流。例:int flussh(FILE *fp);可强制刷新流,没被写入的数据都被传递至内核。
函数:
mode参数:(其实就是打开标准I/O流的方式)
r/rb 打开只读文件,文件必须存在
r+/r+b 打开可读写文件,文件必须存在
w/wb 打开只写文件,文件存在则清0,不存在则建立
w+/w+b/wb+ 打开可读写文件,文件存在则清0,不存在则建立
a/ab 以附加的方式打开只写文件,文件存在则写入的数据会被追加到文件末尾,不存在则建立
a+/a+b/ab+ 以附加的方式打开可读写文件,文件存在则写入的数据会被追加到文件末尾,不存在则建立
1.FILE *freopen(const char *restrict pathname,const char *restrict type,FILE* restrict fp)
//实现每隔一秒打印当前时间到文件fp2中去
#include<stdio.h>
#include<unistd.h>
#include<time.h>
#include<string.h>
int main(int argc,char *argv[])
{
if(argc < 2)
{
fprintf(stderr,"usage:%s Filename.txt\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"a+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
char b[256];
int i = 0;
while(1)//此循环用来判断原来有多少行数据的
{
if(NULL == fgets(b,sizeof(b),fp))
{
break;
}
i++;
}
while(1)
{
/******************时间******************************/
char *wday[]={
"日", "一","二","三","四","五","六"
};
time_t timep;
struct tm *p;
time(&timep);
//printf("time():%d\n",timep);
p = localtime(&timep);
printf("%d------%d年%d月%d日",i,(1900+p->tm_year),(1+p->tm_mon),p->tm_mday);
printf("星期%s,%d点%d分%d秒\n",wday[p->tm_wday],(p->tm_hour),p->tm_min,p->tm_sec);
sleep(1);
i++;
/***********************************************/
freopen(argv[1],"a+",stdout);//输出重定向
}
fclose(fp);
return 0;
}
//实现每隔一秒打印当前时间
#include <stdio.h
#include <string.h>
#include <stdlib.h>
#include <strings.h>
#include <time.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
return -1;
}
FILE *fp = NULL;
if (NULL == (fp = fopen(argv[1], "a+"))) {
perror("fopen");
return -1;
}
int line = 0;
char buf[100];
while (NULL != fgets(buf, sizeof(buf), fp)) {
if (buf[strlen(buf)-1] == '\n')
line++;
}
time_t t;
struct tm *tm;
while (1) {
time(&t);
tm = localtime(&t);
sprintf(buf, "%2d, %4d-%2d-%2d %2d:%2d:%2d\n", ++line, \
tm->tm_year+1900, tm->tm_mon+1, \
tm->tm_mday, tm->tm_hour, tm->tm_min, \
tm->tm_sec);
fputs(buf, fp);
fflush(fp);
sleep(1);
}
fclose(fp);
return 0;
}
2..FILE *open(const char *path,const char *mode)
打开一个流,成功返回FILE*类型的值,失败返回NULL
3.int fclose(FILE *stream)
关闭一个已经打开的流,成功返回0,失败返回EOF(Ctrl+D)(EOF也是文件结束返回标志),并设置errno
4.int fgetc(FILE *stream),int fputc(int c,FILE *stream)
每次读写一个字符
fgetc()成功为下一个字符,处于文件尾或者出错返回EOF
//实现copy
#include<stdio.h>
int main(int argc,char *argv[])
{
if(argc < 3)
{
printf("将filename1复制到filename2中\n");
fprintf(stderr,"usage: %s filename1 filename2\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"r+");
FILE *fp2 = fopen(argv[2],"w+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
int ch;
while(EOF != (ch = fgetc(fp)))
{
fputc(ch,fp2);
}
fclose(fp);
return 0;
}
5.char *fgets(char *s,int size,FILE *stream),int fputs(const char *s,FILE *stream)
每次读写一行
fgets()成功返回非负数,失败返回EOF
//实现copy
#include<stdio.h>
int main(int argc,char *argv[])
{
if(argc < 3)
{
printf("将filename1复制到filename2中\n");
fprintf(stderr,"usage: %s filename1 filename2\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"r+");
FILE *fp2 = fopen(argv[2],"w+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
char ch[1024];
while(NULL != fgets(ch,sizeof(ch),fp))
{
fputs(ch,fp2);
}
fclose(fp);
return 0;
}
6.size_t fread(void *ptr,size_t size,size_t 你们帮,FILE *stream)
size_t fwrite(void *ptr,size_t size,size_t 你们帮,FILE *stream)
两个函数的返回是读/写的对象数
//实现copy
#include<stdio.h>
int main(int argc,char *argv[])
{
if(argc < 3)
{
printf("将filename1复制到filename2中\n");
fprintf(stderr,"usage: %s filename1 filename2\n",argv[0]);
return -1;
}
FILE *fp = fopen(argv[1],"r+");
FILE *fp2 = fopen(argv[2],"w+");
if(NULL == fp)
{
perror("fopen");
return -1;
}
int a;
char ch[100];
while(1)
{
a = fread(ch,1,sizeof(ch),fp);
if(a <= 0)
{
break;
}
fwrite(ch,1,a,fp2);
}
fclose(fp);
return 0;
}
7.int fseek(FILE *stream,long offset,int whence)
long offset是偏移的字节数,whence是相对的偏移位置,参数是:SEEK_SET/SEEK_CUR/SEEK_END,分别是文件头,当前位置,文件尾
//此代码是实现对图片的打码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <strings.h>
int main(int argc, char *argv[])
{
if (argc < 2) {
fprintf(stderr, "Usage: %s <file.bmp>\n", argv[0]);
return -1;
}
FILE *fp = NULL;
if (NULL == (fp = fopen(argv[1], "r+"))) {
perror("fopen");
return -1;
}
fseek(fp, 54, SEEK_SET);
char buf[100*3] = {0};
int i;
for (i = 0; i < 100; i++)
fseek(fp, 300*3, SEEK_CUR);
for (i = 0; i < 100; i++) {
fseek(fp, 100*3, SEEK_CUR);
fwrite(buf, sizeof(buf), 1, fp);
fseek(fp, 100*3, SEEK_CUR);
}
fclose(fp);
return 0;
}
最后我看到几个不错的相关知识在这里分享下,下面是他们的地址:
http://blog.csdn.net/strongwangjiawei/article/details/7786085