下面的例子和上一个类似,不过采用的是标准I/O库而不是系统调用。
代码如下:
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#define BK_NUM 3
struct book
{
char isbn[10];
char name[10];
float price;
}bk[BK_NUM];
int
main( void )
{
printf( "%s\n","Please input the books information:" );
int idx = 0;
for ( ; idx != BK_NUM; ++idx )
{
printf( "%s:", "isbn" );
scanf( "%s", &bk[idx].isbn );
printf( "%s:","name" );
scanf( "%s",&bk[idx].name );
printf( "%s:", "price" );
scanf( "%f", &bk[idx].price );
if ( idx != BK_NUM - 1 )
printf( "%s\n","NEXT" );
}
FILE *fp;
if ( !( fp = fopen( "struct.txt", "w+" ) ) )
{
perror( "OPEN ERROR" );
exit( 1 );
}
if ( fwrite( bk, sizeof( struct book ), BK_NUM, fp ) != BK_NUM )
{
perror( "WRITE ERROR" );
exit( 1 );
}
if ( fseek( fp, sizeof( struct book ), SEEK_SET ) == -1 )
{
perror( "FSEEK ERROR" );
exit( 1 );
}
fpos_t f_pos;
fgetpos( fp, &f_pos );
struct book modify[1];
fread( modify, sizeof( struct book ), 1, fp );
modify[0].price = 100;
fsetpos( fp, &f_pos );
fwrite( modify, sizeof( struct book ), 1, fp );
fseek( fp, 0, SEEK_SET );
fread( bk, sizeof( struct book ), BK_NUM, fp );
printf( "%s\n", "Modified books information:" );
for( idx = 0; idx != BK_NUM; ++idx )
{
printf( "isbn:%s; name:%s; price:%f\n", bk[idx].isbn,bk[idx].name,bk[idx].price );
}
fclose( fp );
exit( 0 );
}
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
功能:从屏幕上读取输入信息,并将其写入二进制文件。定位并修改文件内容,再将其输出。接下来分析其中的几个代码片段及相关函数。
1 FILE *fp;
if ( !( fp = fopen( "struct.txt", "w+" ) ) )
{
perror( "OPEN ERROR" );
exit( 1 );
}
以读写方式打开或创建文件“struct.txt”,操作失败时,输出错误信息。
(1)#include<stdio.h>
FILE *fopen( const char *file_name, const char *mode );
FILE *freopen( const char *file_name,const char *mode, FILE *fp );
FILE *fdopen( int file_des, const char *mode );
a)mode的取值:
“r”或“rb” 以读模式打开,文件必须存在
“w”或“wb” 以写模式打开,并把文件长度截短为0,没有则创建
“a”或“ab” 以写模式打开,在文件尾端追加,没有则创建
“r+”或“rb+”或“r+b” 以读模式打开,文件必须存在
“w+”或“wb+”或“w+b” 以写模式打开,并把文件长度截短为0,没有则创建
“a+”或“ab+”或“a+b” 以写模式打开,在文件尾端追加,没有则创建
注:字母b表示文件是一个二进制文件而不是文本文件,但是Unix/Linux并不区分文本文件和二进制文件,将其都看作二进制文件。
参数mode是字符串而不是字符,所以应该用“r”而不是‘r’。
对应于mode的取值,列出打开一个流的6种不同的方式及限制条件:
限制 r w a r+ w+ a+
文件必须存在 * *
截短文件长度为0 * *
流可读 * * * *
流可写 * * * * *
流可追加 * *
b)freopen:在一个指定的流上打开一个指定的文件,若该流已经打开,则关闭该流;若该留已经定向,则清除该定向。一般用于将一个文件打开为一个预定义的流:标准输入,标准输出或标准出错。
c)fdopen:使一个现有的文件描述符和一个标准的I/O流相结合。此函数常用于由创建管道和网络通信通道函数返回的文件描述符,因为这些特殊类型的文件不能用fopen()打开。fdopen()函数不能截短它为写而打 开的任意文件。
(2)#include<stdio.h>
void perror( const char *s );
#include<string.h>
char *strerror( int err_num );
(1)程序必须在函数出错之后,立即检查error变量,因为它可能会被下一个函数调用所覆盖。
2 if ( fseek( fp, sizeof( struct book ), SEEK_SET ) == -1 )
{
perror( "FSEEK ERROR" );
exit( 1 );
}
fpos_t f_pos;
fgetpos( fp, &f_pos );
定位流,并保存流的当前位置。
(1)#include<stdio.h>
long ftell( FILE *fp );
int fseek( FILE *fp, long offset, int whence );
int fgetpos( FILE *fp, fpos_t *pos );
int gsetpos( FILE *fp, fpos_t *pos );
void rewind( FILE *fp );
以上函数都是用来定位文件流的读写位置的。
转载于:https://www.cnblogs.com/mahy/archive/2011/09/24/2189443.html