上次说日本海啸警报的时候,程序出错。在解析代码的时候,发现了MFC中的一个Bug。
一。问题的产生。
这个程序,用来处理日本各种天气预报数据,包括灾害的预报。如果地震,台风之类的自然灾害到来,程序会把预报数据进行处理,生成相应的警报信息,并在电视上面显示滚动的字幕来提示。程序本身,是几年前公司的其他人写的。里面有涉及到文件读写的地方,有很多地方,用了MFC中自带的文件读写类CStdioFile。
CStdioFile这个文件读写类,估计大家都不陌生。这个类的父类,是CFile类。CStdioFile类本身的功能也很简单。CStdioFile类有一个成员函数是ReadString,函数的定义如下:
virtual LPTSTR ReadString(__out_ecount_z(nMax) LPTSTR lpsz, __in UINT nMax);
virtual BOOL ReadString(CString& rString);
MSDN定义如下http://msdn.microsoft.com/library/x5t0zfyf(VS.80).aspx:
BOOL ReadString(CString& rString);throw( CFileException );
Return ValueA pointer to the buffer containing the text data. NULL if end-of-file was reached without reading any data; or if boolean, FALSE if end-of-file was reached without reading any data.
ReadString函数能直接读取文本中的一行数据到CString中,很方便。读到文件结尾,没有读出任何数据的时候,返回FALSE。很简单的函数,但恰恰是这个函数有Bug。
程序在处理数据的时候,会生成一些临时文件,然后会读取这些临时文件中的数据,读取操作,正是用的CStdioFile的ReadString函数。读取流程很简单:
while(dFile.ReadString(Str_temp))
{doSomething();}
当时的现象为,读取到最后一行,总是直接返回FALSE,怎么也读不出最后一行来。看了看文件的最后一行,包含2176个字符的数据,没有换行符。没有任何异常啊。当时没想到是MFC的Bug,因为以前有这样那样的毛病,多数是预报数据本身有问题,所以这次也是先分析数据了。分析来分析去,没发现这次的数据有什么异常。后来发现如果最后一行的文件不是2176个字符,就能正常读出来。奇了怪了,2176也不是什么特殊长度啊。实验了几次后,觉的是在不对劲。莫非是MFC的Bug?
二。发现问题所在
决定看看MFC的代码再说。做了个简单的测试程序,跟到MFC代码里一看,果然是MFC的问题!测试代码如下:
CStdioFile dFile;dFile.Open("text.txt",CFile::modeRead);