//捕获fopen调用中的错误 #include <stdio.h> #include <errno.h> #include <string.h> #define MYFILE "missing.txt" int main( ) { FILE* fin; fin=fopen( MYFILE,"r" ); if( fin==(FILE*)NULL ) { printf( "%s: %s/n",MYFILE,strerror( errno ) ); exit( -1 ); } fclose( fin ); return 0; } /*数据的读写 标准的I/O库提供了缓冲接口。有两个非常重要的属性: 1、系统是分块进行读写的(一个块通常8KB)。字符I/O都写到FILE缓冲区中, 这个缓冲区满的时候会自动写入介质; 2、如果数据需要送到像控制台终端这样的交互设备,必须设置fflush或者非缓冲 I/O */ /********字符接口**********/ //fputc字符接口实例 #include <stdio.h> #include <errno.h> int main( ) { int i=0; FILE* fout; const char string[ ]={ "This/r/nis a test/r/nfile./r/n/0" }; fout=fopen("inpfile.txt","w"); if( fout==( FILE* )NULL ) { printf( "%s: %s/n","inpfile.txt",strerror( errno ) ); exit( -1 ); } while( string[ i ]!=NULL ) { fputc( ( int )string[ i ],fout ); ++i; } fclose( fout ); return 0; } //fgetc字符接口实例 #include <stdio.h> #include <errno.h> int main( ) { FILE* fin; fin=fopen( "inpfile.txt","r" ); if( fin==( FILE* )NULL ) { printf( "%s: %s/n","inpfile.txt",strerror( errno ) ); exit( -1 ); } int i; while( (i=fgetc( fin ))&&i!=EOF ) { printf( "%c",(char)i ); } return 0; } /* fputc( )是向文件中写入数据;fgetc是从文件中读取数据 总结:字符接口使用简单,但是效率不高,最好是在基于字符串的方法不可使用时才使用字符接口 */ /************字符串接口************/ /*提供字符串读写函数4个。fputs和fgets是简单的字符串接口; fprintf和fscanf更复杂的接口,但提供了更多的功能。 */ //相文件中写入变长字符串 #include <stdio.h> #include <errno.h> #include <stdlib.h> #define LEN 80 int main( ) { char line[ LEN+1 ]; FILE* fout; FILE* fin; //写入数据 fout=fopen( "testfile.txt","w" ); if( fout==( FILE* )NULL ) { printf( "%s: %s/n","testfile.txt",strerror( errno ) ); exit( -1 ); } fin=fdopen( 0,"r" ); //将fin与标准输入流绑定 printf( "Please input some characters,end with CTRL+D:/n" ); //CTRL+D结束输入 while( ( fgets(line,LEN,fin) )!=NULL ) { fputs( line,fout ); } fclose( fout ); fclose( fin ); //读取数据 printf( "/nthe characters read from file is:/n" ); char getLine[ LEN+1 ]; fin=fopen( "testfile.txt","r" ); if( fin==(FILE*)NULL ) { printf( "%s: %s/n","testfile.txt",strerror( errno ) ); exit( -1 ); } fgets( getLine,LEN,fin ); printf( "%s/n",getLine ); fclose( fin ); return 0; } /*fputs向文件中写入,fgets从文件中读取 总结:要注意不可以同时读写同一个文件。 */ //以ASCII格式输出结构体数据 #include <stdio.h> #include <errno.h> #define MAX_LINE 40 #define FILENAME "myfile.txt" typedef struct { int id; float x_coord; float y_coord; char name[ MAX_LINE+1 ]; }MY_TYPE_T; #define MAX_OBJECTS 3 /*Initialize an array of three objects*/ MY_TYPE_T objects[ MAX_OBJECTS ]={ {0,1.5,8.3,"Frist-object"}, {1,4.5,6.3,"Second-object"}, {2,3.5,7.5,"Thrid-object"}, }; int main( ) { int i; FILE* fout; fout=fopen(FILENAME,"w" ); if( fout==( FILE* )NULL ) { printf( "%s: %s/n",FILENAME,strerror( errno ) ); exit( -1 ); } printf( "Writing.../n" ); for( i=0;i<MAX_OBJECTS;++i ) { fprintf( fout,"%d %f %f %s/n",objects[ i ].id,objects[ i ].x_coord, objects[ i ].y_coord,objects[ i ].name); } fclose( fout ); printf("Write over/n"); printf("Read from file/n"); FILE* fin=fopen( FILENAME,"r" ); if( fin==(FILE*)NULL ) { printf( "%s: %s/n",FILENAME,strerror( errno ) ); exit( -1 ); } MY_TYPE_T objects; while( !feof(fin) ) { fscanf( fin,"%d %f %f %s/n",&objects.id,&objects.x_coord, &objects.y_coord,&objects.name); printf("%d %f %f %s/n",objects.id,objects.x_coord, objects.y_coord,objects.name); } fclose( fin ); return 0; } /**************二进制文件的读写*****************/ /*使用fwirte、fread进行二进制文件的读写 读写二进制文件的时候,要注意的重要问题是可移植性和字序问题。 Intel采用小字节序,PowerPC和网络采用大字节序 */ #include <stdio.h> #include <errno.h> #define MAX_LINE 40 #define FILENAME "myfile.bin" typedef struct { int id; float x_coord; float y_coord; char name[ MAX_LINE+1 ]; }MY_TYPE_T; #define MAX_OBJECTS 3 /*Initialize an array of three objects*/ MY_TYPE_T objects[ MAX_OBJECTS ]={ {0,1.5,8.3,"Frist-object"}, {1,4.5,6.3,"Second-object"}, {2,3.5,7.5,"Thrid-object"}, }; int main( ) { int i; FILE* fout; fout=fopen(FILENAME,"w" ); if( fout==( FILE* )NULL ) { printf( "%s: %s/n",FILENAME,strerror( errno ) ); exit( -1 ); } printf( "Writing.../n" ); fwrite( ( void* )objects,sizeof( MY_TYPE_T ),3,fout ); fclose( fout ); //使用fread/fseek/rewind读取二进制结构体数据 printf( "Read from file/n" ); MY_TYPE_T object; FILE* fin=fopen( FILENAME,"r" ); if( fin==( FILE* )NULL ) { printf( "%s: %s/n",FILENAME,strerror( errno ) ); exit( -1 ); } //定位到第三个结构体 fseek( fin,( 2*sizeof( MY_TYPE_T ) ),SEEK_SET ); fread( &object,sizeof( MY_TYPE_T ),1,fin ); printf("%d %f %f %s/n",object.id,object.x_coord, object.y_coord,object.name); fseek( fin,( 1*sizeof( MY_TYPE_T ) ),SEEK_SET ); fread( &object,sizeof( MY_TYPE_T ),1,fin ); printf("%d %f %f %s/n",object.id,object.x_coord, object.y_coord,object.name); //把文件指针复位到文件开头 rewind( fin ); fread( &object,sizeof( MY_TYPE_T ),1,fin ); printf("%d %f %f %s/n",object.id,object.x_coord, object.y_coord,object.name); fclose( fin ); return 0; } /************************************************/ /* 总结:上面所有的函数都是有一些基本API来实现的。比如:open/read/write/fdopen/pread/pwrite. 文件的输入输出API函数也可以用于管道和套接字。另外,文件和字符串操作是面向对象脚本语言的强项,如Ruby,Python. */