📄 12.2.6 文件的读取.txt
字号:
12.2.6 文件的读取
对于文件的读取,首先也需要打开文件,即需要调用 fopen函数得到指向 FILE类型的指针,然后如
果要读取文件的内容,应该调用fread函数。该函数的声明形式如下所示:
size_t fread( void *buffer, size_t size, size_t count , F工LE *stream );
可以看到,与fwrite函数一样, fread函数也有四个参数,并且各参数的含义与fwrite函数的相应
参数含义相同,只是这时第一个参数: buffer是指向用来存放数据的缓冲区的指针。
下面,我们就在File程序CFileView类的OnFileRead函数中添加如例 12-5所示的代码,利用C语言提
供的函数实现文件的读取操作。
例12-5
'
void CFileView: :OnFileRead()
FILE *pF工le=fopen ( "1 . txt " , "r" ) ;
char ch[100] ;
fread(ch , 1 , 100 , pFile) ;
fclose (pFile) ;
MessageBox (ch) ;
在上述如例 12-5所示代码中,首先调用fopen函数得到想要读取其内容的文件结构指针,本例将读
取上面写入操作使用的文件: l.txt。因为只是要读取文件中的数据,所以我们使用"r"的方式打开。
接着,定义了一个 100个字符的字符数组,用来接收读取的数据。然后调用fread函数读取刚才写入
文件操作时使用的文件: l.txt中的内容。同样,在文件读取操作完成之后,可以使用 fclose函数
关闭文件。最后,调用MessageBox函数将读取到的数据显示出来。
Build井运行 File程序,利用相应菜单命令先写入文件,再读取文件,这时在程序显示的消息框中
就可以看到读取到的数据,如图 12.6所示。
图 12.6读取文件数据后显示结果不正确
‘~~ 1443
第12
可是,我们发现该消息框显示的文字中,开始部分是我们程序中写入的数据: "ftp://
www.suruin-org",但后面显示了一串乱码。这里再一次强调,在C语言中,字符串是以"\。"符号结
束的。在显示字符串时,系统会寻找"\。"字符。而这里定义的1∞个元素的字符数组: ch,它里面
的数据是随机的,可能有许多数据都是不可读的,系统会从该字符数组的开始地址依次往后查找,
由于在其中没有找到气。"字符,于是它就把这些不可读的数据显示出来了,结果就是我们所看到的
乱码。因此,我们应该在读取到的数据之后添加气。"字符,以便作为字符串的结尾。
有多种方法可以向一个字符串添加"飞。"字符,以表示该字符串的结束。
·第一种方法
可以在写入数据时多写入一个字节,例如上面写入操作向l.txt文件中写入的字符串 ''http://www.
sunxin.org"是21个字节,可以在写入时在其后再添加一个字节,其内容设置为"飞。",即这时的写
入文件代码如例 12-6所示。
例 12-6
void CFileView : : OnFileWrite()
FILE *pFile=fopen (" 1 . txt" , "w") ;
char buf[22) = ''http://www . sunxin. org" ;
buf [21) = '\o ' ;
fwrite(buf , 1 , 22 ,pFile) ;
fclose (pFile) ;
运行File程序,单击【文件操作飞写入文件】菜单项后,可以发现生成的l.txt文件大小是22个字节。
读者可以以二进制方试打开该文件,可以看到最后一个数据就是: 0。读者应注
意:"飞。"就是 0。在读取文件数据时,"\。"字符也将被读取,当把读取到的数据存入字符数组后,
就可以根据其中的"\。"字符判图 12.7读取文件数据后断出字符串的结尾。这时,再单击【文件操
作L读取文件】菜单显示的正确结果,在弹出的消息框中就可以看到正确的内容了,结果如图
12.7所示。
这种方式的缺点是增加了文件大小,虽然只是多写了一个字节,但是从文件大小的精确度角度来说,
这种方式不是很好。
·第二种方法
在定义字符数组之后,利用C语言中的memset函数将这个字符数组中的所有数据都设置为o(代码如例
12-7所示〕。然后在程序中读取文件时,读取到多少数据就会在该字符数组中存放多少数据,字符
数组中剩下的数据全是0。这样,在字符串显示时遇到"飞\0"就表示该字符串结束了,因此就能正确
地显示数据。
例 12-7
void CFileView: : OnFileRead() F工LE *pFile=fopen("1.txt " , "r" );
char ch[100] ;
memset(ch, O, 100);
fread(ch , 1 , 100 ,pFile) ;
fclose(pFile) ;
MessageBox (ch) ;
·第二种方法
有时在读取文件时,并不知道文件的大小,这里我们定义的字符数组固定为 100个元素,如果容量
不够怎么办呢?所以在程序中需要获取文件的长度,然后根据这个长度来分配存放该数据的内存。可
以利用C语言中的ftell函数来得到文件的长度。 ftell函数将返回文件指针当前的位置。因此,可
以先利用 fseek函数将文件指针移动到文件的结尾处,然后利用ftell函数就可以得到文件指针当前
的位置,也就是文件的长度。具体代码如例 12-8所示。
例12-8
1. void CFileView::OnFileRead()
2. {
3. FILE *pFile=fopen( "l .txt " , "r") ;
4. char *pBuf;
5. fseek(pFile , O, SEEK_END) ;
6. int len=ftell(pFile) ;
7 . pBuf=new char[len+1] ;
8. fread(pBuf,1,len,pFile) ;
9. pBuf[len]=0 ;
10. fclose (pFile) ;
11. MessageBox(pBuf) ;
12. }
在上述例 12-8所示代码中,得到文件长度 Clen)之后,分配内存以便用来保存读取到的数据,这时
应该多分配一个字节,用来存放表示字符串结尾的"旧"字符,然后就可以读取文件的内容了,并将
数组的最后一个元素设置为o (例12-8所示代码的第9行代码〉。对于数组来说,它的索引从O开始,
因此对于元素个数为 len+1的数组来说,索引为len的元素就是它的最后一个元素。接下来就可以调
用 fclose函数关闭文件。最后调用 MessageBox函数显示读取到的数据。
再次运行File程序,单击【文件操作\读取文件】菜单项,你会发现这时程序显示的消息框中显示的
数据又出现了乱码。我们对上述例12-8所示代码进行分析,在我们将文件指针移动到文件结尾后(上
述如例 12-8所示代码的第5行),再次读取文件时(上述如例 12-8所示代码的第 8行),就是从文件
指针指向的下一个写入位置处开始读取,而此时文件指针已经到了文件结尾,当然是读取不到数据
的。这是在对文件进行操作时,移动文件指针后经常会犯的一个错误。在这里,我们应该在读取之
前将文件指针再次移动到文件开始处,当然这可以通过fseek函数来实现,但这里我们利用另一个函
数: rewind来实现这一功能,该函数的功能是将文件指针重新放置到文件的开始处。 rewind函数只
有一个参数,就是指
向 FILE结构体的指针。因此在上述读取代码(上述如例 12-8所示代码的第 8行)之前,添加下面这
条语句,将文件指针重新放置到文件开始处。
rewind (pFile) ;
再次运行 File程序,单击【文件操作飞读取文件】菜单项,这时可以发现程序显示的消息框中显示
的结果正确了。这里,再次提醒读者在使用 C语言函数对文件进行读取操作时,应注意以下几点:
·
在读取文件数据时,如果是字符数据,通常在定义用来保存该数据的字符数组时,在字符数据个数
的基础上,多分配一个字节,以存放表示字符串结尾的字符 :"\。"。
·
在读取文件内容时,应正确地设置文件指针的位置。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -