Chinaunix首页 | 论坛 | 博客
  • 博客访问: 213249
  • 博文数量: 127
  • 博客积分: 1998
  • 博客等级: 上尉
  • 技术积分: 1432
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-07 16:41
文章分类

全部博文(127)

文章存档

2014年(41)

2013年(1)

2012年(85)

分类: C/C++

2012-03-17 15:40:54


  1. struct _IO_FILE {
  2.   int _flags; /* High-order word is _IO_MAGIC; rest is flags. */
  3. #define _IO_file_flags _flags
  4.  
  5.   /* The following pointers correspond to the C++ streambuf protocol. */
  6.   /* Note: Tk uses the _IO_read_ptr and _IO_read_end fields directly. */
  7.   char* _IO_read_ptr; /* Current read pointer */
  8.   char* _IO_read_end; /* End of get area. */
  9.   char* _IO_read_base; /* Start of putback+get area. */
  10.   char* _IO_write_base; /* Start of put area. */
  11.   char* _IO_write_ptr; /* Current put pointer. */
  12.   char* _IO_write_end; /* End of put area. */
  13.   char* _IO_buf_base; /* Start of reserve area. */
  14.   char* _IO_buf_end; /* End of reserve area. */
  15.   /* The following fields are used to support backing up and undo. */
  16.   char *_IO_save_base; /* Pointer to start of non-current get area. */
  17.   char *_IO_backup_base; /* Pointer to first valid character of backup area */
  18.   char *_IO_save_end; /* Pointer to end of non-current get area. */
  19.  
  20.   struct _IO_marker *_markers;
  21.  
  22.   struct _IO_FILE *_chain;
  23.  
  24.   int _fileno;
  25. #if 0
  26.   int _blksize;
  27. #else
  28.   int _flags2;
  29. #endif
  30.   _IO_off_t _old_offset; /* This used to be _offset but it's too small. */
  31.  
  32. #define __HAVE_COLUMN /* temporary */
  33.   /* 1+column number of pbase(); 0 is unknown. */
  34.   unsigned short _cur_column;
  35.   signed char _vtable_offset;
  36.   char _shortbuf[1];
  37.  
  38.   /* char* _save_gptr; char* _save_egptr; */
  39.  
  40.   _IO_lock_t *_lock;
  41. #ifdef _IO_USE_OLD_IO_FILE
  42. };
  43. typedef struct _IO_FILE FILE;

这是FILE结构体的定义。文件(file)是程序设计中的一个重要的概念。所谓"文件"一般指:存储在外部介质上的数据的集合。一批数据是以文件的形式存放在外部介质(如磁盘)上的。操作系统是以文件为单位对数据进行管理的,也就是说,如果想找存在外部介质上的数据,必须先按文件名找到所指定的文件,然后再从该文件中读取数据。要向外部介质上存储数据也必须先建立一个文件(以文件名标识),才能向它输出数据。

文件的打开和关闭

和其它高级语言,对文件读写之前应该"打开"文件,在使用结束之后应"关闭"该文件。

fopen()

ANSI C 规定了标准输入输出函数库,用fopen()函数来实现打开文件。fopen()函数的调用方式通常为:

FILE *fp;

fp=fopen(文件名使用文件的方式);

例如:

fp=("d:\\aa.txt", "r");

它表示:要打开D盘根目录下aa.txt文件来读数据。fopen()函数带回指向aa.txt文件的指针并赋给fp,这样fp就和aa.txt相联系了,或者说,fp指向aa.txt文件了。可以看出,在打开一个文件时,通知给编译系统以下三个信息:1.需要打开的文件名,也就是准备访问的文件的名字。2.使用文件的方式(读还是写等)3.让哪一个指针变量指向被打开的文件。

使用文件的方式见表10.1

10.1

 

文件使用方式

 

"r" (只读)

为输入打开一个文本文件

"w" (只写)

为输出打开一个文本文件

"a" (追加)

向文本文件尾增加数据

"rb" (只读)

为输入打开一个二进制文件

"wb” (只写)

为输出打开一个二进制文件

"ab" (追加)

向二进制文件尾增加数据

"r+" (读写)

为读/写打开一个文本文件

"w+" (读写)

为读/写建立一个新的文本文件

"a+" (读写)

为读/写打开一个文本文件

"rb+" (读写)

为读/写打开一个二进制文件

"wb+" (读写)

为读/写建立一个新的二进制文件

"ab+" (读写)

为读/写打开一个二进制文件

 

说明:

1. "r"方式打开的文件只能用于向计算机输入而不能用于向该文件输出数据,而且该文件应该已经存在,不能打开一个并不存在的用于"r"方式的文件(即输入文件),否则出错。

2. "w"方式打开的文件只能用于向该文件写数据,而不能用来向计算机输入。如果原来不存在的文件,则在打开时新建一个以指定名字命名的文件。如果原来已经存在一个以该文件名命名的,则在打开时将该文件删除,重新建立一个新文件。

3. 如果希望向文件末尾添加新数据,用"a"方式打开,但此时文件必须存在,否则将出现出错信息。打开时位置指针移到文件末尾。

4. "r+"方式时该文件已经存在,以便能向计算机输入数据。 "w+"方式则建立一个文件,先向文件写数据,然后可以读此文件中的数据。

5. 如果不能实现"打开"的任务,fopen函数将会带回一个出错信息,此时fopen函数将会带回一个空指针值NULL。常用下面的方法打开一个文件:

if ((fp = fopen("file1", " r "))= =NULL)

{ printf ("cannot open this file\n ");

exit(0);

即先检查是否出错,如果有错就在终端上输出"cannot open this file"exit函数的作用是关闭所有文件,终止正调用过程。待程序员检查出错误,修改后再运行。

6. 用以上方式可以打开文本文件或二进制文件,用同一种缓冲文件系统来处理文本文件和二进制文件。

7. 在用文本文件向计算机输入时,将回车换行符转换为一个换行符,在输出时把换行符转换为回车和换行两个字符。在用二进制文件时,不进行这种转换。

8. 在程序开始运行时,系统自动打开三个标准文件:标准输入、标准输出、标准出错输出。通常这三个文件都与终端相联系。系统自动定义了三个 文件指针stdinstdoutstderr分别指向终端输入、终端输出、标准出错输出。如果在程序中指定要从stdin所指的文件输入数据,就是指从终端键盘输入数据。

fclose()

在使用完一个文件后应该关闭它,以防止它再被误用。"关闭"就是使文件指针变量不指向该文件,此后不能再通过该指针对其相连的文件进行读写操作,除非再次打开,使该指针变量重新指向该文件。

fclose函数关闭文件。fclose函数调用的一般形式为: fclose(文件指针);

例如:fclose(fp); fclose函数打开文件时所带回的指针赋给了fp,现把该文件关闭。应养成在程序终止上前关闭所有使用的文件的习惯,如果不关闭文件将会丢失数据。fclose函数返回一个值,顺利执行关闭操作返回值为0;如果返回非0值,则表示关闭时有错误。

 

文件的读写

fputc() 和 fgetc()

一、 fputc函数把一个字符写到磁盘文件中去。其一般形式为 fputc(ch,fp);

其中ch是要输出的字符,它可以是一个字符常量也可以是一个字符变量。fp是文件指针变量,它从fopen 函数得到返回值。 fputc函数的作用是将字符(ch的值)输出到fp所指向的文件上去。如果输出成功fputc函数的返回值就是输出的字符;如果输出失败,则返回一个EOF

二、fgetc函数

从指定文件读入一个字符,该文件必须是以读或读写方式打开的。fgetc函数的调用形式为:

ch = fgetc(fp);

fp为文件型指针变量,ch为字符变量。fgetc函数带回一个字符赋给ch。如果在执行fgetc读字符时遇到文件结束符,函数返回一个文件结束标志EOF。如果想从一个磁盘文件顺序读入字符并在屏幕上显示出来可以:

ch = fgetc(fp);

while(ch! = EOF)

{

putcher( ch );

ch = fgetc(fp);

}

注意:EOF不是可输出字符,因此不能在屏幕上显示。如果想顺序读入一个二进制文件中的数据,可以用: while( !feof (fp) )

{ c = fgetc(fp);

当未遇文件结束,feof(fp)的值为0。!feof(fp)的值为1,这种方法也适用于文本文件。

三、fputc函数和fgetc函数使用举例

例:从键盘输入一些字符,逐个把它们送到键盘上去,直到输入一个"#"为止。

#include

void main(void)

{FILE *fp;

char ch,filename[10];

scanf("%s ",filename);

if ((fp = fopen ( filename, "w ")) = =NULL)

{

printf("cannot open file\n ");
exit(0);

}

ch = getchar( );
while (ch!= ’#’)

{

fputc(ch,fp);

putchar(ch);

ch=getchar( );

}

fclose(fp);

}

运行情况如下:file1.c (输入磁盘文件名)

computer and c# (输入一个字符串)

computer and c (输入一个字符串)

本例运行时,从键盘输入磁盘文件名"file1.c",然后输入要写入该磁盘文件的字符"computer and c",同时在屏幕上显示这些字符。

fread() 和 fwrite()

getcputc函数可以用来读写文件中的一个字符。但是常常要求一次读入 一组数据, fread函数和fwrite函数可以用来读写一个数据块。它们一般调用形式为:

fread (buffer,size,count,fp);

fwrite(buffer,size,count,fp);

buffer:是一个指针。对fread它是读入数据的存放地址。对fwrite是输出数据的地址。

size:要读写的字节数。

count:要进行读写多少个size字节的数据项。

fp:文件型指针。

如果文件以二进制形式打开,用freadfwrite函数就可以读写任何类型的信息,如 fread(f,4,2,fp); 其中f是一个实型数组名。一个实型变量占4个字节。这个函数从fp所指向的文件读入2次数据,存储到数组f中。如果有如下一个结构体类型:

sturt student_type

{ char name[10];

int num;

int age;

char addr[30];

} stud[40]; 结构体数组stud40个元素,每一个元素用来存放一个学生数据,假设学生的数据已存放在磁盘文件中,可以用下面的语句读入40个学生数据。

for(i = 0; i<40;i++)

fread(&stud[i],sizeof(struct student_type),1,fp);

同样,以下的语句可以将内存中学生数据输出到磁盘文件中。

for (i=0;i<40;i++)

fread(&stud[i],sizeof(struct student_type),1,fp);

下面写出一个完整的程序。

例:从键盘输入4个学生的有关数据,然后把它们转存到磁盘文件中去。

# include

#define SIZE 4

struct student_type

{ char name[10];

int num;

int age;

char addr[15];

} stud[SIZE];

void save( void)

{ FILE *fp;

int i;

if ((fp=fopen("stu_list","wb"))= =NULL)

{

print("cannot open file\n");

return;

}

for(i=0;i

if(fwrite(&stud[i],sizeof(struct student_type),1,fp)!=1)

printf("file write error\n");

}

void main(void)

{ int i;

for (i=0;i

scanf("%s%d%d%s",stud[i].name,&stud[i].num,&stud[i].age, stud[i].addr);

save( );

}

fprintf() 与fscanf()

fprintf函数和fscanf函数与 printf函数、scanf 函数相仿,都是格式化读写函数。只有一点不同:fprintf函数和fscanf函数的读写对象不是终端而是磁盘文件。一般调用方式为:

fprintf(文件指针,格式字符串,输出表列);

fscanf(文件指针,格式字符串,输入表列);

例如: fprintf(fp"%d,%6.2f"i,t);它的作用是将整型变量i和实型变量t的值按%d%6.2f的格式输出到fp指向的文件上。如果 i=3,t=4.5,则输出到磁盘文件上的是以下的字符串:

34.50

同样,用以下fscanf 函数可以从磁盘文件上读入ASCⅡ字符:fscanf(fp"%d,%f"&i,&t);

这样将磁盘文件中的数据送给变量i,t

其他函数

一、putw函数和getw函数

这两个函数用来对磁盘文件读写一个字。例如 putw(10,fp)的作用是将整数10输出到fp 指向的文件。而i=getw(fp); 的作用是从磁盘文件读一个整数到内存,赋给整型变量i

二、fgets函数和fputs函数

fgets函数的作用是从指定文件读入一个字符串。如:fgets(str,n,fp);

fp指向的文件输入n-1个字符,并把它们放到字符数组str中。如果在读入 n-1个字符结束之前遇到换行符或EOF,读入即结束。字符串读入后在最后加一个’\0’字符,fgets 函数的返回值是str的首地址。

fputs函数的作用是从指定文件输出一个字符串。如:fputs("China",fp);

把字符串"China"输出到fp指向的文件,fputs函数中第一个参数可以是字符串常量、字符数组名或字符型指针。输出成功函数值为0;失败时为非零值。

文件的定位

rewind()

文件中有一个指针,指向当前读写的位置。如果顺序读写一个文件,每次读写一个字符,则读写完一个字符后,该位置指针自动移动指向下一个字符位置。如果想改变这样个规律,强制使位置指针指向其它指定的位置,可以用有关函数。

rewind函数的作用是使位置指针重新返回文件的开头。此函数没有返回值。

例:有一个磁盘文件,第一次使它显示在屏幕上,第二次把它复制到另一文件上。

#include

void main(void)

{ FILE *fp1,*fp2;

fp1 = fopen("file1.c","r");

fp2 = fopen("file2.c","w");

while(!feof(fp1)) putchar(getc(fp1));

rewind(fp1);

while(!feof(p1)) putc(getc(fp1),fp2);

fclose(fp1);

fclose(fp2);

}

在第一次显示在屏幕以后,文件file1.c的位置指针已指到文件末尾,feof的值为真,执行 rewind 函数,使文件的位置指针重新定位于文件开头,并使feof函数的值恢复为假。

fseek()

如果位置指针是按字节位置顺序移动的,就是顺序读写。如果可以将位置指针按需要移动到他、任意位置,就可以实现随机读写。所谓随机读写是指读完上一个字符后,并不一定要读写其后续的字符,而可以读写文件中任意所需的字符。用fseek函数可以实现改变文件的位置指针。fseek函数的调用形式为 fseek(文件类型指针,位移量,起始点)

fseek函数用来移动文件内部位置指针,其调用形式为: fseek(文件指针,位移量,起始点); 其中:“文件指针”指向被移动的文件。 “位移量”表示移动的字节数,要求位移量是long型数据,以便在文件长度大于64KB 时不会出错。当用常量表示位移量时,要求加后缀“L”。“起始点”表示从何处开始计算位移量,规定的起始点有三种:文件首,当前位置和文件尾。
其宏定义为:

起始点    表示符号    数字表示
──────────────────────────
文件首    SEEK_SET    0
当前位置   SEEK_CUR    1
文件末尾   SEEK_END     2

位移量指以起始点为基点,向前移动的字节数。一般要求位移量是long型数据。

下面是fseek函数调用的几个例子:

fseek(fp,100L,0); 将位置指针移到离文件头100个字节处。

fseek(fp,50L,1); 将位置指针移到离当前位置50个字节处。

fseek(fp,-10L,2); 将位置指针从文件末尾处向后退10个字节。

例如,fseek(fp,100L,0);其意义是把位置指针移到离文件首100个字节处。还要说明的是fseek函数一般用于二进制文件。在文本文件中由于要进行转换,故往往计算的位置会出现错误。文件的随机读写在移动位置指针之后, 即可用前面介绍的任一种读写函数进行读写。由于一般是读写一个数据据块,因此常用fread和fwrite函数。下面用例题来说明文件的随机读写。

ftell()

ftell函数的作用是得到文件的当前位置,如果ftell函数返回值为-1L,表示出错。例如:

i=ftell(fp);

if (i = = -1L) printf("error\n"); 变量i存放当前位置,如果调用函数出错,则输出"error"

从键盘输入一个字符串,将其中的小写字母全部转换成大写字母,然后输出到一个磁盘文件"test"中保存。输入的字符串以""结束。

阅读(1026) | 评论(0) | 转发(0) |
0

上一篇:Ubuntu 进单用户模式

下一篇:assert

给主人留下些什么吧!~~