本文转自:http://www.cnblogs.com/JiMuStudio/archive/2011/07/17/2108496.html
 
CStdioFile类的声明保存再afx.h头文件中。
CStdioFile类继承自CFile类,CStdioFile对象表示一个用运行时的函数fopen打开的c运行时的流式文件。流式文件是被缓冲的,而且可以以文本方式(默认)或者二进制方式打开。
CStdioFile类不支持CFile类中的Duplicate、LockRange、UnlockRange函数,如果你使用了,会得到CNotSupportedException类的错误。
CStringFile类默认的是按照Text模式操作文件。CFile 类默认的是按照二进制模式操作文件。
这里大致说明一下二进制模式和Text模式的区别。
二进制模式:对于一行的结尾我们必须输入”/r/n”,才能表示回车换行的效果。
Text模式:”/r”回车的工作是自动完成的,我们只需要写入”/n”即可。所以我们再使用文本模式时要主要,当我们从外部读入文件时,”/r/n”会被翻译成”/n”,写入文件时,我们对于回车换行只需提供”/n”,即可,”/r/n”会被写入到文件中。
m_pStream成员变量:
      打开文件的指针。
 
构造函数:
CStdioFile();
CStdioFile(FILE *pOpenStream);
CStdioFile(LPCTSTR lpFileName, UINT nOpenFlags);
throw(CFileException);
FILE *pOpenStream:指的是c运行函数fopen调用后返回的文件指针。
LPCTSTR lpFileName:指的是被打开的文件(绝对地址或相对地址)
UINT nOpenFlags:指的是CFile类中所描述的打开文件的方式。
 
virtual LPTSTR ReadString(LPTSTR lpsz, UINT nMax);
throw(CFileException);
如果使用该函数读取文本文件,当遇到”/r/n”,停止读取,并去掉”/r”,保留”/n”,并在字符串尾部增加”/0”,nMax的长度包含有”/0”字符,
实际的分析如下:
如果nMax <= 字符数,读取(nMax-1)个字符+0x00;
如果nMax = 字符数 + 1,读取nMax个字符+0x00;
如果nMax > 字符数,读取nMax个字符+0x0A(”/n”) + 0x00;
如果文件有多行,则当文件没有读完时,返回NOT NULL,读到文件尾,返回NULL。
 
BOOL ReadString(CString& rString);
throw(CFileException);
读取一行文本到rString中,遇到回车换行符停止读取,回车和换行符均不读到rString中,尾部也不添加”0x00”。
如果文件有多行,则当文件没有读完时,返回TRUE,读到文件尾,返回FALSE。
 
virtual void WriteString(LPTSTR lpsz);
throw(CFileException);
将缓冲区中的数据写入到与CStdioFile对象相关联的文件中,不支持CString类型数据写入,结束的”/0”不被写入到文件中,lpsz缓冲区中的所有换行符被替换为回车换行符即”/n”转换为”/r/n”。

\

一、前言

工作中经常要对存贮在txt文件ADC采样的数据进行处理,虽然有着现成的工具软件可以对数据进行分析,然而不具有针对性,因此需要根据不同的数据处理要求,采用MFC编程实现,那么问题就在于如何通过编程实现对文本文件中数据的读取。

二、CStdioFile

CStdioFile类的声明保存在afx.h头文件中。

CStdioFile类继承自CFile类,CStdioFile对象表示一个C运行函数fopen打开的的流式文件。流式文件是被缓冲的,而且可以以文本方式(默认)或者二进制方式打开。

CStdioFile类不支持CFile类中的Duplicate、LockRange、UnlockRange函数,如果你使用了,会得到C Not Supported Exception类的错误。

CStringFile类默认的是按照Text模式操作文件。

CFile 类默认的是按照二进制模式操作文件。

这里大致说明一下二进制模式和Text模式的区别。

二进制模式:对于一行的结尾我们必须输入'\r\n',才能表示回车换行的效果。

Text模式:'\r'回车的工作是自动完成的,我们只需要写入'\n'即可。在使用Text模式时从外部读入文件时,'\r\n'会被翻译成'\n',写入文件时,我们对于回车换行只需提供'\n',即可,'\r\n'会被写入到文件中。

成员变量

m_pStream成员变量:打开文件的指针。

构造函数

CStdioFile();

CStdioFile(FILE *pOpenStream);

CStdioFile(LPCTSTR lpFileName, UINT nOpenFlags);

throw(CFileException);

FILE *pOpenStream:指的是c运行函数fopen调用后返回的文件指针。

LPCTSTR lpFileName:指的是被打开的文件(绝对地址或相对地址)

UINT nOpenFlags:指的是CFile类中所描述的打开文件的方式。

读函数

virtual LPTSTR ReadString(LPTSTR lpsz, UINT nMax);

throw(CFileException);

如果使用该函数读取文本文件,当遇到'\r\n',停止读取,并去掉'\r',保留'\n',并在字符串尾部增加'\0',nMax的长度包含有'\0'字符,实际的分析如下:

如果nMax <= 字符数,读取(nMax-1)个字符+0x00;

如果nMax = 字符数 + 1,读取nMax个字符+0x00;

如果nMax > 字符数,读取nMax个字符+0x0A('\n') + 0x00;

如果文件有多行,则当文件没有读完时,返回NOT NULL,读到文件尾,返回NULL。

BOOL ReadString(CString& rString);

throw(CFileException);

读取一行文本到rString中,遇到回车换行符停止读取,回车和换行符均不读到rString中,尾部也不添加'0x00'。如果文件有多行,则当文件没有读完时,返回TRUE,读到文件尾,返回FALSE。

写函数

virtual void WriteString(LPTSTR lpsz);

throw(CFileException);

将缓冲区中的数据写入到与CStdioFile对象相关联的文件中,不支持CString类型数据写入,结束的'\0'不被写入到文件中,lpsz缓冲区中的所有换行符被替换为回车换行符,即'\n'转换为'\r\n'。

三、CStdioFile类编程原理

假如要进行的文件操作只是简单的读写整行的字符串,那么最好使用CStdioFile。首先把文本文件的每行数据读到一个缓冲区,然后使用sscanf把它转化为字符格式。

例如在一个txt文件里每一行数据格式是这样的:

A1 A2 A3 A3 ......An

那么读取的主体代码是:

CStdioFile File;  // 定义一个CStdioFile类变量File

CString FileData; // 定义一个CString,作为一个缓冲区

//定义n个临时字符串变量,大小依据实际情况,这里暂设为10

char TempStr1[10],TempStr2[10]......TempStrN[10];

File.ReadString(FileData); // 将一行数据读到缓冲区

//将该行数据的n个字符读到n个临时字符串变量

sscanf(FileData,"%s %s %s %s ......%s",TempStr1,TempStr2......TempStrN);

这种读法的一个好处是对文本格式要求不严,如下面的格式也可以

(前面可有未知个空格) A1 A2 (两个数据之间也可有未知个空格) A3 A3 ......An

四、CStdioFile类编程应用

以一个单文档程序为例。该程序的主要功能是读取文本文件的坐标数据,然后在客户区里用直线将这些坐标连起来,并显示。

1、 启动Visual C++6.0,生成一个单文档的工程,将该工程命名为ReadCoodinate。

2、 添加一个“读取文本数据”的菜单项。

3、 给视图类添加两个public变量:

CArray<CPoint,CPoint> m_PointArray; // 用于记录坐标点数据

int m_PointNum; // 用于记录坐标点个数,在视图类构造函数中初始化为0。

4、 给“读取文本数据”添加相应的单击消息响应函数。代码如下:

void CReadCoodinateView::OnReaddata()

{

// TODO: Add your command handler code here

CFileDialog dlg(TRUE); // 定义一个文件对话框变量

if(dlg.DoModal()==IDOK)

{

CString m_FilePath = dlg.GetPathName(); //取得文件路径及文件名

CStdioFile File;

File.Open(m_FilePath,CFile::modeRead); //以读模式打开文本文件

CString FileData; //定义一个CString变量作为缓冲区

//定义两个临时字符串,并初始化为'\0'

char TempStr1[10];

char TempStr2[10];

memset(TempStr1,'\0',10);

memset(TempStr2,'\0',10);

File.ReadString(FileData);//读取第一行数据,第一行数据为坐标点数据

sscanf(FileData,"%s",TempStr1);

m_PointNum = atoi(TempStr1); // 获取坐标点个数

//逐行读取坐标数据

for (int i = 0;i<m_PointNum;i++)

{

File.ReadString(FileData);

sscanf(FileData,"%s %s",TempStr1,TempStr2);

m_PointArray.Add(CPoint(atoi(TempStr1),atoi(TempStr2)));//将其存入坐标点数组

}

CDC *pDC = GetDC(); //获取设备环境;

//根据坐标点绘出直线

for (i = 0;i<m_PointNum-1;i++)

{

pDC->MoveTo(m_PointArray[i].x, m_PointArray[i].y);

pDC->LineTo(m_PointArray[i+1].x, m_PointArray[i+1].y);

}

ReleaseDC(pDC); //使用完后,释放设备环境

}

}

其中示例数据文件的格式是这样的:(第一行为坐标个数,余下的是坐标点数据)

5

10 20

30 40

45 85

100 120

200 300

这个程序的一个优点是对文本数据格式并不严格,只要x坐标和y坐标中间有一个空格就可以了。若要将文本数据传化为其它形式的数据(如将字符型数据转化为浮点型可以利用函数atof()),其中原理是一样的。

CStdioFile类学习笔记<转>的更多相关文章

  1. System类学习笔记

    最近在学习源码的过程中发现:很多深层次的代码都用到了一个类System类,所以决定对System类一探究竟 本文先对System类进行了剖析,然后对System类做了总结 一.首先对该类的中的所有字段 ...

  2. zt C++ list 类学习笔记

    C++ list 类学习笔记 分类: C++ 2011-09-29 00:12 7819人阅读 评论(0) 收藏 举报 listc++iteratorvectorcconstructor 双向循环链表 ...

  3. GUI学习之五——QAbstractButton类学习笔记

    今天总结一下AbstractButton类的学习笔记. 一.描述 AbstractButton是对各种按键的抽象类他的继承关系是这样的 首先,QAbstractButton继承了QWidget类的各种 ...

  4. java.util.Properties类 学习笔记

    学习目标:   1.认识properties文件,理解其含义,会正确创建properties文件. 2.会使用java.util.Properties类来操作properties文件. 3.掌握相对路 ...

  5. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  6. ThreadLocal类学习笔记

    这个类在java1.2中就出现了,线程独有的变量(每个线程都有一份变量),使用它的好处之一就是可以少传许多参数. 在哪里用到它呢?有连接池的地方就有它的身影,连接池包括数据库连接池,网络连接池等. i ...

  7. C++ list 类学习笔记

    双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面一个元素.在STL中,list和vector一样,是两个常被使用的容器.和vector不一样的是,list不支持对元素 ...

  8. 转载:C++ vector 类学习笔记

    声明:本文转载自http://blog.csdn.net/whz_zb/article/details/6827999 vector简介 vector是STL中最常见的容器,它是一种顺序容器,支持随机 ...

  9. 转载:C++ list 类学习笔记

    声明:本文转自http://blog.csdn.net/whz_zb/article/details/6831817 双向循环链表list list是双向循环链表,,每一个元素都知道前面一个元素和后面 ...

随机推荐

  1. eclispe新导入的文件有个小红叉号(x)的问题

    关于这个问题,我百度了很久,后面发现很简单的就解决了:我觉得可能大家的问题不一样,或许解决方法可能是一样的: 参考链接:https://zhidao.baidu.com/question/616762 ...

  2. ANDROID NFC读M1卡

    <?xml version="1.0" encoding="utf-8"?> <android.support.constraint.Cons ...

  3. luogu P1038借教室【Noip提高组2012】

    这道题我读完题目的第一感觉是: 这不就是个线段树??用线段树维护区间最小值,检查是否满足订单要求即可判断. 对于修改操作直接在区间上进行. 据说会卡一卡线段树,但是貌似写一个懒标记,连zkw线段树都不 ...

  4. hdu2825(AC 自动机)

    hdu2825 题意 给出一些字符串,要求构造一个长度为 \(n\) 的字符串至少包括其中的 \(k\) 个,问有多少种字符串满足条件. 分析 AC自动机 构造状态转移,然后 状态压缩DP 即可. \ ...

  5. hdu6041

    hdu6041 题意 给出一个仙人掌. 如果一个无向连通图的任意一条边最多属于一个简单环,我们就称之为仙人掌.所谓简单环即不经过重复的结点的环. 求前 \(K\) 小生成树 . 分析 仙人掌中每个环中 ...

  6. 【Android】 HttpClient 发送REST请求

    直接po代码吧,第一个是一个枚举类型的类,是四种rest http请求,get/post/put/delete: public enum HttpRequestMethod { HttpGet { @ ...

  7. luogu P3368 【模板】树状数组 2

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  8. [BZOJ 1407] Savage

    Link:https://www.lydsy.com/JudgeOnline/problem.php?id=1407 Solution: 由于此题里n的范围很小,因此可以直接从小到大枚举m 那么问题转 ...

  9. [Codeforces 32E] Hide-and-Seek

    Brief Intro: 给两个人的坐标,一堵墙和一面镜子,询问两人能否看见对方 Solution: 一道以分类讨论为主的计算几何题, 分别讨论两人坐标连线是否经过墙/镜子即可, 难点在于如何求出点x ...

  10. Exercise01_07

    public class Outcome{ public static void main(String[] args){ double x, y; x=4*(1.0-1.0/3+1.0/5-1.0/ ...