文件I/O流
对于每一个ANSI C程序而言,至少打开三个流:标准输入(stdin)、标准输出(stdout)、标准错误(stderr),他们都是一个指向FILE结构的指针。
标准输入为:键盘设备
标准输出为:终端或屏幕。
标准库I/O一般情况:
1. 程序必须为同时处于活动状态的每个文件声明一个指针变量,其类型为: FILE* ,这个指针指向一个结构,当它处于活动状态时由流使用。
2. 流通过fopen函数打开,打开流的时候,必须指定需要访问的文件或者设备已经访问的方式。fopen函数和操作系统去验证文件或者设备确实存在,验证访问方式,然后初始化FILE结构
3.根据需要对文件进行读取和写入。
4.最后,fclose函数可以关闭流。关闭一个流可以防止与它相关的文件被再次访问,保证任何存储于缓冲区中的数据被正确的写入文件中。
1.FILE * fopen ( const char * filename, const char * mode );
1> r 只读 ,文件必须已存在
2> w 只写,如果文件不存在则创建,如果文件已存在则把文件长度截断(Truncate)为0字节再重新写,也就是替换掉原来的文件内容
3> a 只能在文件末尾追加数据,如果文件不存在则创建
4> r+ 允许读和写,文件必须已存在
5> w+ 允许读和写,如果文件不存在则创建,如果文件已存在则把文件长度截断为0字节再重新写
6> a+ 允许读和追加数据,如果文件不存在则创建
使用fopen打开文件时如果出错,fopen将返回NULL并设置errno,必须对此进行处理:
if (fp == NULL) {
perror("fopen");
exit(1);
}
2.int fclose ( FILE * stream );//需与fopen配套使用(打开流一定要关闭)
字符I/O:
3.int getc ( FILE * stream );
4.int putc ( int character, FILE * stream );
int main()
{
FILE *fp = fopen("log.txt", "wt");
if (NULL == fp)
{
perror("fopen");
return 1;
}
//int i = 0; //将hello czf!写入log.txt
//while (i++ < 10)
//{
// fputs("hello czf!\n", fp);
//}
//int ch; //计算文件中的!
//size_t count = 0;
//do{
// ch = getc(fp);
// if ('!' == ch)
// {
// printf("%c : %d\n",ch, count);
// }
// count++;
//} while (ch != EOF);
//printf("end = %d\n", ch);
int ch = 'A';
while (ch <= 'Z') //将A-Z逐个写入fp
{
putc(ch, fp);
putc('\n', fp);
ch++;
}
fclose(fp);
return 0;
}
未格式化的行I/O
char * gets ( char * str );
int puts ( const char * str )
5.char * fgets ( char * str, int num, FILE * stream );
6.int fputs ( const char * str, FILE * stream );
int main()
{
char buf[255] = {0};
while (1) //从标准输入读入,打印到标准输出
{
gets(buf);
if (strcmp("quit", buf) == 0)
{
break;
}
//printf("echo:%s\n", buf);
puts(buf);
}
printf("quit!\n");
FILE *fp = fopen("myfile.txt", "w");
if (NULL == fp)
{
perror("fopen");
return 1;
}
char buf[128];
while (1) //从文件读到缓冲区,再从缓冲区读到屏幕
{
fgets(buf, 10, fp);
if (feof(fp))
{
printf("end of file! quit!\n");
break;
}
fputs(buf, stdout);
fflush(stdout);
Sleep(1000);
}
char buf[128];
while (1)
{
printf("enter:");
fgets(buf, 128, stdin);
if (strncmp("quit", buf, 4) == 0)
{
break;
}
fputs(buf, fp);
}
fclose(fp);
return 0;
}
格式化的行I/Oint scanf ( const char * format, ... ); //返回成功转换和分配的字段的数量
int printf ( const char * format, ... );
//返回值为打印的字符数,出现错误,打印负值 printf("%d", printf("%d",2)); 21
输出缓存刷新到目标地址的时机:
1.\n
2.scanf
3.exit
4.内核缓存满
5.fflush(stdout);
7.int fscanf ( FILE * stream, const char * format, ... );
8.int fprintf ( FILE * stream, const char * format, ... );
#include <stdio.h>
#include <string.h>
int main()
{
float f;
char buf[16] = {0};
char name[16] = {0};
FILE *fp = fopen("log.txt", "w+");
if(NULL == fp)
{
perror("fopen");
return 1;
}
fprintf(fp, "%f %s", 3.14159, "PI");
rewind(fp); //将流的读写位置充值到最开始
fscanf(fp, "%f %s", &f, buf);
printf("%f, %s\n", f, buf);
fclose(fp);
return 0;
}
二进制I/O:
9.size_t fread ( void * ptr, size_t size, size_t count, FILE* stream ); <缓冲区名> <一个单元的大小> <要读多少单元> <流>
10.size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream ); <写出缓冲区> <单元大小> <多少个单元> <流>
#include <stdio.h>
int main()
{
char buff[] = {'A' , 'B' , 'C'};
FILE *fp = fopen("myfile.bin","wb+");
if(NULL == fp){
perror("fopen");
return 1;
}
fwrite(buff,sizeof(char),sizeof(buff),fp);
fclose(fp);
return 0;
}
11.int fseek(FILE *stream, long offset, int whence); <流> <偏移量> <偏移位置>//进行文件写入位置的定位
fseek的whence和offset参数共同决定了读写位置移动到何处,whence参数的含义如下:
SEEK_SET
从文件开头移动offset个字节
SEEK_CUR
从当前位置移动offset个字节
SEEK_END
从文件末尾移动offset个字节
offset可正可负,负值表示向前(向文件开头的方向)移动,正值表示向后(向文件末尾的方向)移动,如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸,从原来的文件末尾到fseek移动之后的读写位置之间的字节都是0。
12. void rewind(FILE *stream) == int fseek(FILE *stream, 0, SEEK_SET) //回到流的最开始
13.long ftell(FILE *stream);//报告每次写入的位置
14.int fflush(FILE *stream);
15.对比EOF和feof函数的区别?
feof()判断文件结尾: 二级制文本的结束标志
EOF 文本文件的结尾标志
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int main()
{
char buf[20];
FILE *fp = fopen("/bin/ls","rb");
if(NULL == fp)
{
perror("fopen");
return 1;
}
fseek(fp,0,SEEK_END); //将写入位置移动到文件结尾
long lsize = ftell(fp); //报告文件为准
rewind(fp); //把光标移动到文件开始
printf("size -> %d\n",lsize);
char *buff = (char*)malloc(sizeof(char)*lsize);
assert(buff);
ssize_t t = fread(buff,lsize, 1 ,fp); //将fp读进buff
FILE *ofp = fopen("myls","wb+");
if(NULL == ofp){
perror("fopen");
return 1;
}
fwrite(buff,lsize, 1, ofp);
fclose(fp);
fclose(ofp);
free(buff);
// float d;
// char name[20];
// FILE *fp = fopen("czf.txt","w+");
// if(NULL == fp)
// {
// perror("fopen");
// return 1;
// }
//
// int i = 0;
// for(; i < 5; i++){
// printf("Please Enter a name:\n");
// gets(name);
// fprintf(fp, "Name %d is [%-10.20s]\n",i+1 ,name );
// }
// fprintf(fp, "%s %f\n","PI" ,3.14 );
// rewind(fp);
// fscanf(fp,"%s %f",&buff, &d);
// printf("%s %f\n",buff,d);
// fclose(fp);
return 0;
}