C++中getc与putc的操作的切换

来源:互联网 发布:矩阵的计算方法 编辑:程序博客网 时间:2024/05/29 12:27

1 getc()函数putc()函数

getc()函数的作用是从流中读取字符,而putc()函数的作用是向流中写入字符。

getc()函数的格式为

int getc(   

   FILE *stream   

);

其中,参数stream为指定的流,函数的返回值是读取到的字符。

putc()函数的格式为

int putc(  

   int c,  

   FILE *stream   

);

其中,参数c表示要写入的字符,stream表示指定的流;函数的返回值是写入到流中的字符。

2 fopen_s()函数

getc()函数putc()函数的参数中都有读取或者写入流对象。该流对象可以通过fopen_s()函数获得。

2.1 函数格式

该函数的作用是打开指定的文件,并且获取该文件对应的流。其格式为

errno_t fopen_s(   

   FILE** pFile,  

   const char *filename,  

   const char *mode   

);

参数pFile是文件指针的指针,表示了获取到的文件流;filename指定了文件的名称;mode表示对文件的访问权限。如果成功打开文件,则该函数的返回值是0,否则是错误代码。

2.2 读写切换

通过对fopen_s()函数获取到的文件流进行读写操作时,需要注意的是,该函数的第三个参数,即访问权限是"r+"时,可以对指定文件进行读和写的操作(该文件被打开用来“更新”)。但是,当从读操作换成写操作时,输入操作必须遇到一个EOF标识符(也就是说,必须全部读取完毕后才能写)。如果不想全部读取完毕后再能写,就必须使用一个设置文件位置函数作为中介。设置文件位置的函数可以是fsetpos()fseek()rewind()。当从写操作换成读操作时,必须调用fflush()函数或者设置文件位置函数作为中介。

2.3 文件位置函数

2.2读写切换”中提到的文件位置函数包括了fsetpos()fseek()rewind()

2.3.1 fsetpos()函数

fsetpos()函数的作用是设置流位置指示器(stream-position indicator)的位置。该函数的格式为

int fsetpos( FILE *stream, const fpos_t *pos );

其中,参数stream表示指定的流;pos表示将指示器移动到的位置;如果设置流位置指示器成功,则返回值为0,否则为非0

2.3.2 fseek()函数

fseek()函数的作用是设置文件指针(file pointer)的位置。该函数的格式为

int fseek(   

   FILE *stream,  

   long offset,  

   int origin   

);

其中,参数stream表示指定的流;offset指定了文件指针要移动的距离;origin指定了文件指针移动的起始位置;如果设置文件指针成功,则返回值为0,否则为非0

2.3.3 rewind()函数

rewind()函数函数的作用是将文件指针移动到文件的起始位置处。该函数的格式为

void rewind(  

   FILE *stream   

);

其中,参数stream表示指定的流。

2.3.4 fflush()函数

fflush()函数的作用是将流中的内容写入到文件中。该函数的格式为

int fflush(   

   FILE *stream   

);  

其中,参数stream表示指定的流;如果写入成功,则返回值为0,否则为非0

3 程序分析

CSDN论坛上有帖子问到通过fopen_s()函数打开指定的文件,之后通过getc()函数读取文件中的字符,将读取到的字符变为大写之后,再写入到文件中,完成将小写字母转换成大写字母的功能。其代码片段为

    while((ch=getc(source))!=EOF)    {        ch=toupper(ch);        putc(ch,source);    }


其中,source是通过fopen_s()函数打开的指定文件流。

在以上代码片段中,就涉及到了2.2读写切换”中提到的文件流读操作和写操作之间的切换。当通过getc()读取到文件中的一个字母后,通过toupper()函数将其变为大写,此时对流的操作状态为读取,因此在putc()函数对流进行写入操作之前,需要调用fsetpos()函数设置流位置指示器的位置。getc()函数在读取了流中当前位置之后,会将流位置指示器的位置向后移动一位,而要实现的功能是将原先的小写字母替换为大写字母。

 因此,在写入大写字母之前需要调用fsetpos()流位置指示器的位置再移动回读取时的位置处;最后再调用putc()将小写字母替换为大写字母,注意此时的流位置指示器的位置会再次向后移动一位,如图1所示。


图1 代码流程

在调用了putc()函数完成了文件流的写入之后,当再次通过getc()读取文件流之前,还需要通过fsetpos()函数或者fflush()函数进行操作流的状态转换。修改后的代码如下所示:

fpos_t pos = 1;while ((ch = getc(source)) != EOF){ch = toupper(ch);//将流的读状态转换为写状态fgetpos(source, &pos);//获取流位置指示器的当前位置pos -= 1;//将流位置指示器的位置向前移动一位fsetpos(source, &pos);//设置流位置指示器的位置putc(ch, source);//将流的写状态转换为读状态fflush(source);       //或者通过fsetpos()函数实现写状态向读状态的转换//pos += 1;//fsetpos(source, &pos);}
由于使用getc()函数和putc()函数之前存在多次状态切换,可以考虑使用fread()函数将文件中的字母一次性全部读出来,之后将其变为大写字母后,再使用fwrite()函数将其写入。fread()函数和fwrite()函数的用法请参见

http://blog.csdn.net/hou09tian/article/details/73657925

原创粉丝点击