有书共读22《C primer Plus》

1、标准I/O包除了可移植以外还有两个好处。第一,标准I/O有许多专门的函数简化了处理不同I/O的问题。第二,输入和输出都是缓冲的。

2fopen函数功能打开磁盘内的文件,使程序能对文件进行读写。

函数原型:FILE *fopen(const char *path, const char * mode);

传入参数说明:

*path——所要打开的文件和路径

*mode——打开文件的模式

返回值:文件顺利打开后,指向该流的文件指针就会被返回,若文件打开失败则返回NULL。注意:一般打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以fopen()后需要做错误判断及处理。

参数说明:参数path字符串包含欲打开的文件路径及文件名;参数mode字符串则代表着流形态,提供了“r”、“w”、“a”、“+”、“b”、“r”六种模式选择符号,常用的模式如下:

r” :以只读方式打开文件,该文件必须存在。

w” :打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

a” :以附加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留。(EOF符保留)

r+” :以可读写方式打开文件,该文件必须存在。

w+” :打开可读写文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。

a+”:以附加方式打开可读写的文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾后,即文件原先的内容会被保留。 (原来的EOF符不保留)

rb” :只读打开一个二进制文件,只允许读数据。

wb” :只写打开或建立一个二进制文件,只允许写数据。

ab” :追加打开一个二进制文件,并在文件末尾写数据。

rb+” :读写打开一个二进制文件,允许读写数据,文件必须存在。

wb+” :读写打开或建立一个二进制文件,允许读和写。

ab+” :读写打开一个二进制文件,允许读,或在文件末追加数据。

rt” :只读打开一个文本文件,只允许读数据。

wt” :只写打开或建立一个文本文件,只允许写数据。

at” :追加打开一个文本文件,并在文件末尾写数据。

rt+” :读写打开一个文本文件,允许读和写。

wt+” :读写打开或建立一个文本文件,允许读写。

at+” :读写打开一个文本文件,允许读,或在文件末追加数据。

3、gets函数:从标准输入设备读字符串函数,其可以无限读取,不会判断上限,以回车结束读取,所以程序员应该确保缓冲区的空间足够大,以便在执行读操作时不发生溢出。

功能:从stdio流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中。换行符不作为读取串的内容,读取的换行符被转换为‘\0’空字符,并由此来结束字符串。

返回值:读入成功,返回与参数缓冲区相同的指针;读入过程中遇到EOF(End-of-File)或发生错误,返回NULL指针。所以在遇到返回值为NULL的情况,要用ferrorfeof函数检查是发生错误还是遇到EOF。

4、putc函数:功 能:输出字符到指定流中

putc()与fputc()等价。不同之处为:当putc函数被定义为宏时,它可能多次计算stream的值。

关于fputc():

原型:int fputc(int ch,FILE*fp)

功能:在fp所指向的文件的当前读写位置写入一个字符。写入字符成功则函数返回值为该字符的ASCII值,写入字符不成功则返回值为EOF。

向文件写入一个字符后,文件读写位置指针向后移动一个字节。

与putc一样一般用法为“fputc(ch,fp)”,包含在头文件“stdio.h”中

5、exit()函数

所在头文件:stdlib.h(如果是“VC6.0”的话头文件为:windows.h)

功 能: 关闭所有文件,终止正在执行的进程。

exit(0)表示正常退出,

exit(x)(x不为0)都表示异常退出,这个x是返回给操作系统(包括UNIX,Linux,和MS DOS)的,以供其他程序使用。

stdlib.h: void exit(int status);//参 数status,程序退出的返回值

6、fclose函数:功能是关闭一个流。注意:使用fclose()函数就可以把缓冲区内最后剩余的数据输出到内核缓冲区,并释放文件指针和有关的缓冲区。

函数原型:int fclose( FILE *fp );

返回值:如果流成功关闭,fclose 返回 0,否则返回EOF(-1)。(如果流为NULL,而且程序可以继续执行,fclose设定error number给EINVAL,并返回EOF。)

7、fprintf函数:是C/C++中的一个格式化库函数,位于头文件<cstdio>或<bits/stdc++.h>中,其作用是格式化输出到一个流/文件中;

函数原型:int fprintf( FILE *stream, const char *format, [ argument ]...),fprintf()函数根据指定的格式(format)向输出流(stream)写入数据(argument)。

参数说明:FILE*stream:文件指针

const char*format:输出格式

[argument]:附加参数列表

函数说明:fprintf( )会根据参数format 字符串来转换并格式化数据, 然后将结果输出到参数stream 指定的文件中, 直到出现字符串结束('\0')为止。

8、fscanf函数:位于头文件<stdio.h>中,函数原型为int fscanf(FILE*stream, constchar*format, [argument...]); 其功能为根据数据格式(format)从输入流(stream)中写入数据(argument);与fgets的差别在于:fscanf遇到空格和换行时结束,注意空格时也结束,fgets遇到空格不结束。

9、fgets函数:从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize-1个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回buf,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。

函数原型

char *fgets(char *buf, int bufsize, FILE *stream);

参数

*buf:字符型指针,指向用来存储所得数据的地址。

Bufsize:整型数据,指明存储数据的大小。

*stream:文件结构体指针,将要读取的文件流。

返回值

1.  成功,则返回第一个参数buf;

2.  在读字符时遇到end-of-file,则eof指示器被设置,如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL;

3.  如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变。

10、fputs函数:具有的功能是向指定的文件写入一个字符串(不自动写入字符串结束标记符‘\0’)。成功写入一个字符串后,文件的位置指针会自动后移,函数返回值为非负整数;否则返回EOF(符号常量,其值为-1)。

函数原型:int fputs(const char *str, FILE *stream);

1*str:这是一个数组,包含了要写入的以空字符终止的字符序列。

2*stream:指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流

11rewind函数:C程序中的库函数,功能是将文件内部的指针重新指向一个流的开头。
功能:将文件内部的位置指针重新指向一个流(数据流/文件)的开头
注意:不是文件指针而是文件内部的位置指针,随着对文件的读写文件的位置指针(指向当前读写字节)向后移动。而文件指针是指向整个文件,如果不重新赋值文件指针不会改变。rewind函数作用等同于(void)fseek(stream, 0L, SEEK_SET);

用 法: void rewind(FILE *stream);

12、fseek函数:函数设置文件指针stream的位置。如果执行成功,stream将指向以fromwhere(偏移起始位置:文件头0(SEEK_SET),当前位置1(SEEK_CUR),文件尾2(SEEK_END))为基准,偏移offset指针偏移量)个字节的位置。如果执行失败(比如offset超过文件自身大小),则不改变stream指向的位置。

功能:重定位(数据流/文件)上的文件内部位置指针

注意:文件指针指向文件/流。位置指针指向文件内部的字节位置,随着文件的读取会移动,文件指针如果不重新赋值将不会改变或指向别的文件。

函数原型:int fseek(FILE *stream, long offset, int fromwhere);

返回值:成功,返回0,失败返回-1,并设置error的值,可以用perror()函数输出错误。

fseek position the file(文件) position(位置) pointer指针 for the file referenced by stream to the byte location calculated by offset.

13、ftell函数:用于得到文件位置指针当前位置相对于文件首的偏移字节数。在随机方式存取文件时,由于文件位置频繁的前后移动,程序不容易确定文件的当前位置。该函数对大于231-1文件,即:2.1G以上的文件操作时可能出错。

13、fflush函数:功能是冲洗流中的信息,该函数通常用于处理磁盘文件。fflush()会强迫将缓冲区内的数据写回参数stream 指定的文件中。

14、fgetpos函数:

函数原型: int fgetpos(FILE * restrict stream,fpos_t * restrict pos);

函数功能:在pos所指的位置放置一个fpos_t值,这个值描述了文件中的一个位置。

返回值:如果成功,函数返回0;否则返回一个非零值。

15、fsetpos函数:将文件指针定位在pos指定的位置上。该函数的功能与前面提到的fgetpos相反,是将文件指针fp按照pos指定的位置在文件中定位。pos值以内部格式存储,仅由fgetpos和fsetpos使用。

16、feof函数:功能是检测流上的文件结束符,如果文件结束,则返回非0值,否则返回0(即,文件结束:返回非0值,文件未结束,返回0值),文件结束符只能被clearerr()清除。

17、ferror,函数名,在调用各种输入输出函数(如 putc.getc.fread.fwrite等)时,如果出现错误,除了函数返回值有所反映外,还可以用ferror函数检查。 它的一般调用形式为 ferror(fp);如果ferror返回值为0(假),表示未出错。如果返回一个非零值,表示出错。应该注意,对同一个文件 每一次调用输入输出函数,均产生一个新的ferror函 数值,因此,应当在调用一个输入输出函数后立即检 查ferror函数的值,否则信息会丢失。在执行fopen函数时,ferror函数的初始值自动置为0。

18、ungetc()函数:用于将一个字符退回到输入流中,这个退回的字符会由下一个读取文件流的函数取得。

原型:int ungetc(char c,  FILE *stream);
参数:c为要退回的字符,stream为要退回的输入流。
返回值:若该函数执行成功,返回非零值;否则,返回0。

19、setvbuf()函数:用来设定文件流的缓冲区。

原型:int setvbuf(FILE * stream, char * buf, int type, unsigned size);
stream为文件流指针,buf为缓冲区首地址,type为缓冲区类型,size为缓冲区内字节的数量。
参数说明:IOFBF (满缓冲):当缓冲区为空时,从流读入数据。或当缓冲区满时,向流写入数据。_IOLBF (行缓冲):每次从流中读入一行数据或向流中写入—行数据。_IONBF (无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区

返回值:成功返回0,失败返回非0。

20、fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0。

函数原型:size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;

参数:buffer用于接收数据的内存地址

size要读的每个数据项的字节数,单位是字节

count要读count个数据项,每个数据项size个字节.

stream输入流

21、write()函数: 是 C 语言标准库中的一个文件处理函数,功能是向指定的文件中写入若干数据块,如成功执行则返回实际写入的数据块数目。该函数以二进制形式对文件进行操作,不局限于文本文件。

用法:size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

返回值:返回实际写入的数据块数目

(1)buffer:是一个指针,对fwrite来说,是要获取数据的地址;

(2)size:要写入内容的单字节数;

(3)count:要进行写入size字节的数据项的个数;

(4)stream:目标文件指针

(5)返回实际写入的数据项个数count。

说明:写入到文件的哪里?这个与文件的打开模式有关,如果是w+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变,stream的位置移动count个数;如果是a+,则从文件的末尾开始添加,文件长度加大。

fseek对此函数有作用,但是fwrite函数写到用户空间缓冲区,并未同步到文件中,所以修改后要将内存与文件同步可以用fflush(FILE *fp)函数同步。

22ANSIC提供两种文件打开模式:二进制和文本。以二进制模式打开文件时,可以逐字节读取文件;以文本模式打开文件时,会把文件内容从文本的系统表示法映射为C表示法。对于系统UNIXLinux系统,这两种模式完全相同。

通常,输入函数getc()fgets()fscanf()fread()都从文件开始出按顺序读取文件。然而,fseek()ftell()函数让程序可以随机访问文件中的任意位置。Fgetpos()fsetpos()把类似的功能扩展至更大的文件。与文本模式相比,二进制模式更容易进行随机访问。

23、编程练习:

13-7a:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 int
ch1, ch2;
 FILE
* f1;
 FILE
* f2;
 if
(argc != 3)
 {
 printf("Usage: %s file1 file2\n",
argv[0]);
 exit(EXIT_FAILURE);
 }
 if
((f1 = fopen(argv[1], "r")) == NULL)
 {
 printf("Could not open file %s for
input\n", argv[1]);
 exit(EXIT_FAILURE);
 }
 if
((f2 = fopen(argv[2], "r")) == NULL)
 {
 printf("Could not open file %s for
input\n", argv[2]);
 exit(EXIT_FAILURE);
 }
 ch1
= getc(f1);
 ch2
= getc(f2);
 while (ch1 != EOF || ch2 != EOF)
 {
 while (ch1 != EOF && ch1 != '\n') 
 {
 putchar(ch1);
 ch1
= getc(f1);
 }
 if
(ch1 != EOF)
 {
 putchar('\n');
 ch1
= getc(f1);
 }
 while (ch2 != EOF && ch2 != '\n') 
 {
 putchar(ch2);
 ch2
= getc(f2);
 }
 if
(ch2 != EOF)
 {
 putchar('\n');
 ch2
= getc(f2);
 }
 }
 if
(fclose(f1) != 0)
 printf("Could not close file %s\n",
argv[1]);
 if
(fclose(f2) != 0)
 printf("Could not close file %s\n",
argv[2]);
 return 0;
}
13-7b:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
 int
ch1, ch2;
 FILE
* f1;
 FILE
* f2;
 if
(argc != 3)
 {
 printf("Usage: %s file1 file2\n",
argv[0]);
 exit(EXIT_FAILURE);
 }
 if
((f1 = fopen(argv[1], "r")) == NULL)
 {
 printf("Could not open file %s for
input\n", argv[1]);
 exit(EXIT_FAILURE);
 }
 if
((f2 = fopen(argv[2], "r")) == NULL)
 {
 printf("Could not open file %s for
input\n", argv[2]);
 exit(EXIT_FAILURE);
 }
 ch1
= getc(f1);
 ch2
= getc(f2);
 while (ch1 != EOF || ch2 != EOF)
 {
 while (ch1 != EOF && ch1 != '\n') /*
skipped after EOF reached */
 {
 putchar(ch1);
 ch1
= getc(f1);
 }
 if
(ch1 != EOF)
 {
 if
(ch2 == EOF)
 putchar('\n');
 else
 putchar(' ');
 ch1
= getc(f1);
 }
 while (ch2 != EOF && ch2 != '\n') /*
skipped after EOF reached */
 {
 putchar(ch2);
 ch2
= getc(f2);
 }
 if
(ch2 != EOF)
 {
 putchar('\n');
 ch2
= getc(f2);
 }
 }
 if (fclose(f1)
!= 0)
 printf("Could not close file %s\n",
argv[1]);
 if
(fclose(f2) != 0)
 printf("Could not close file %s\n",
argv[2]);
 return 0;
}

使用命令行参数,ab运行的结果如下:


13-12

#include <stdio.h>
#include <stdlib.h>
#define ROWS 20
#define COLS 30
#define LEVELS 10
const char trans[LEVELS + 1] = "
.':~*=&%@";
void MakePic(int data[][COLS], char
pic[][COLS], int rows);
void init(char arr[][COLS], char ch);
int main()
{
 int
row, col;
 int
picIn[ROWS][COLS];
 char
picOut[ROWS][COLS];
 char
fileName[81];
 FILE
* infile;
 init(picOut, 'S');
 printf("Enter name of file: ");
 scanf("%80s", fileName);
 if
((infile = fopen(fileName, "r")) == NULL)
 {
 fprintf(stderr, "Could not open data
file.\n");
 exit(EXIT_FAILURE);
 }
 for
(row = 0; row < ROWS; row++)
 for
(col = 0; col < COLS; col++)
 fscanf(infile, "%d",
&picIn[row][col]);
 if
(ferror(infile))
 {
 fprintf(stderr, "Error getting data from
file.\n");
 exit(EXIT_FAILURE);
 }
 MakePic(picIn, picOut, ROWS);
 for
(row = 0; row < ROWS; row++)
 {
 for
(col = 0; col < COLS; col++)
 putchar(picOut[row][col]);
 putchar('\n');
 }
 return 0;
}
void init(char arr[][COLS], char ch)
{
 int
r, c;
 for
(r = 0; r < ROWS; r++)
 for
(c = 0; c < COLS; c++)
 arr[r][c] = ch;
}
void MakePic(int data[][COLS], char
pic[][COLS], int rows)
{
 int
row, col;
 for
(row = 0; row < rows; row++)
 for
(col = 0; col < COLS; col++)
 pic[row][col] = trans[data[row][col]];
}


全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务