hur.cn - 华软网

 热门搜索

VC读取TXT文件,数据还原问题

  作者:未知    来源:网络    更新时间:2009/11/9
我建立一个TXT备份资料,内容格式为:标志位判断+空格+变量。
如:bit1=true 18562  
    bit2=false 0
    bit3=true 7679
    bit4=true 8642
    bit5=false 0
        .
.
.
我想判断标志位,如果是true,则将数值赋给对应的变量。比如我读取bit1=true,则将18562赋值给变量i1,读取bit2=false,则不将0赋给i2,读取bit3=true,将7679赋值给i3。期望哪位大侠能解答。
---华软 网友回答---
赋值之前判断一下啊  这个有什么难的?
---华软网友回复---
顶下 ~~~~
---华软网友回复---
还不如用ini呢
对照好操作

bit1=18562  
bit2=0 
bit3=7679 
bit4=8642 
bit5=0 

省掉了一步
---华软网友回复---
我建议您换成xml或ini资料都比txt资料好。
---华软网友回复---
这似乎很简单吧。用CStdioFile逐行读取。然后就是字符串拆分了。从右起头截取空格,那么右侧的就是数值,左侧的就是标志。对左侧的再用等于号举行拆分,就能够猎取bit1和true了。然后想干啥就干啥。
---华软网友回复---
有什么问题吗?解析资料时犯错了吧?
代码看一下?
---华软网友回复---
CStdioFile   sfile;  
  if(!sfile.Open("c:\\txt.txt",CFile::modeRead))  
  {  
  AfxMessageBox("Open   file   error!");  
  return;  
  }  
  CString   strLine;  
  while(sfile.ReadString(&strLine))
{
    BOOL bNeedToGetData = (strLine.Find("true") == -1) ? FALSE : TRUE;
    if(bNeedToGetData)
    {
        int i = strLine.ReverseFind(' '); //倒序查找空格
        CString strData = strLine.Mid(i , strLine.GetLength() - i);
        //赋值
    }
};  
sfile.Close();
---华软网友回复---
用基本资料读取,逐行措置惩罚分析。
关头是得动手做。
---华软网友回复---
晕  手写的  发的有点快  很难看  格式化一遍 重发
C++">
CStdioFile  sfile; 
if(!sfile.Open("c:\\txt.txt",CFile::modeRead)) 

AfxMessageBox("Open  file  error!"); 
return; 

CString  strLine; 
while(sfile.ReadString(&strLine))
{
BOOL bNeedToGetData = (strLine.Find("true") == -1) ? FALSE : TRUE;
if(bNeedToGetData)
{
int i = strLine.ReverseFind(' '); //倒序查找空格
CString strData = strLine.Mid(i , strLine.GetLength() - i);
//赋值
}
}; 
sfile.Close();

---华软网友回复---
很简单啊,一次读一行,存到字串链表中,找到关头的key字串修改后,再把字串保存到原资料中。
用文档序列化就简单了。
---华软网友回复---
引用 10 楼 pady_pady 的回复:
很简单啊,一次读一行,存到字串链表中,找到关头的key字串修改后,再把字串保存到原资料中。
用文档序列化就简单了。

这个解析起来的确不难,由于有固定的格式。可是像这些配置的东西用ini或xml才是对照好的。
---华软网友回复---
C++">char *szBuf="bit1=true 18562";
char buf1[32],buf2[32],buf3[32];
sscanf(szBuf, "%[^=]=%[^ ] %s", buf1,buf2,buf3);

---华软网友回复---
引用 3 楼 wtx_sonery 的回复:
还不如用ini呢
对照好操作

bit1=18562 
bit2=0
bit3=7679
bit4=8642
bit5=0

省掉了一步



的确是这样的,你这样搞法会累死的。照旧搞成配置资料的方式吧。

---华软网友回复---
引用 12 楼 bobob 的回复:
C/C++ codechar*szBuf="bit1=true 18562";char buf1[32],buf2[32],buf3[32];
    sscanf(szBuf,"%[^=]=%[^ ] %s", buf1,buf2,buf3);

这段代码收藏了...  
---华软网友回复---
引用 12 楼 bobob 的回复:
C/C++ codechar*szBuf="bit1=true 18562";char buf1[32],buf2[32],buf3[32];
    sscanf(szBuf,"%[^=]=%[^ ] %s", buf1,buf2,buf3);

代码如此优雅   耐人寻味  受教了 !
---华软网友回复---
建议用其余资料格式
---华软网友回复---
建议换成ini格式。

XML格式。

---华软网友回复---
    bit1=true 18562  
    bit2=false 0 
    bit3=true 7679 
    bit4=true 8642 
    bit5=false 0 

首先,建议你运用 INI 方式 存取。
或,从基本上改变你的设计 。
比如 bit5 false 0 
这样好措置惩罚一点。

其实,都很简单的。
---华软网友回复---
我学习VC大概3个月,很多东西都没有接触,现在唯一了解的是用TXT资料读取和存储数据。对前面大侠所说的用ini和xml等资料存储,我还不会,我把代码贴出来,请大侠帮助改一改。
---华软网友回复---
代码以下:
void CTTTxtDlg::OnButton1() 
{
char buf; //读取资料的临时变量
int length=0; //数据长度
int num=0; //数据个数
int maxlength=0; //数据的最大长度
char *Temp; //截取到的每一个数据的字符串
CFile DataFile;
DataFile.Open("C:\\temp.txt",CFile::modeRead);
while(DataFile.Read(&buf,sizeof(char)))  //这个while找出数据的最大长度和个数
{
if((buf>=48&&buf<=57)||(buf>=97)||(buf<=122)) //如果是0-9或a-z之间
{
length++;               //数字长度加1
}
else if((buf==13)||(buf==0x20)) //遇到回车或空格数据个数加1
{
num++;                //数字个数加1,数据的最大个数也是num
DataFile.Seek(1,CFile::current);//指针移动一个字节
if(length>maxlength)  //找出数据的最大长度
{
maxlength=length;
}
length=0;
}

}
double *DataArray;     //寄存数据
DataArray=new double[num];
Temp=new char[maxlength];
int IniNumOfDA=0; //存储数据数组的计数变量
int NumOfTemp=0; //临时记录数据长度的变量
DataFile.SeekToBegin();   //设定资料读取位置,重新重新读取
while(DataFile.Read(&buf,sizeof(char)))
{

if((buf>=48&&buf<=57)||(buf>=97)||(buf<=122))   //如果是0-9或a-z之间
{
Temp[NumOfTemp]=buf;     //将读取的字符放入Temp中
if(NumOfTemp<maxlength)
{
NumOfTemp++;
}
}
else if((buf==13)||(buf==0x20)) //遇到回车或空格
{
DataFile.Seek(1,CFile::current);
if(IniNumOfDA<num)
{
for (int i=NumOfTemp;i<maxlength;i++)
{
Temp[NumOfTemp]=NULL; //将Temp清空,准备保存下一个数据
}
DataArray[IniNumOfDA]=atof(Temp);//将bit=true,整数,全保存留DataArray[IniNumOfDA]中
IniNumOfDA++;
NumOfTemp=0;
}
}
}

DataFile.Close();
if(DataArray[4]=="bit3=true")//判断DataArray[4]存储的是否是"bit3=true",是,将变量数据7679显示出来
{m_edit=DataArray[5];}//我将7679读出来,显示在编辑框中
delete DataArray;
delete Temp;

}

---华软网友回复---
上面的代码将数组转化为字符串有毛病,我在char buf; //读取资料的临时变量前面加上
CString RBuf;        //中间值
将DataFile.Close();后面的改成
RBuf=DataArray[4];
if(RBuf=="bit3=true")//判断DataArray[4]存储的是否是"bit3=true",是,将变量数据7679显示出来
{m_edit=DataArray[5];}//我将7679读出来,显示在编辑框中 
delete DataArray;
delete Temp;
这样程序有警告,将double转化成char可能丧失数据
---华软网友回复---
ini资料读取方式, 比如C:\a.ini资料的内容以下
[COMMON]
bit1=18562  
bit2=0 
bit3=7679 
bit4=8642 
bit5=0 

读取方式为:

CString strFileName = "C:\\a.ini";
int iRes = 0;
iRes = ::GetPrivateProfileInt("COMMON","bit1",0/*默许值*/,strFileName.GetBuffer(0));
if(iRes!=0)
{
 //赋值操作
}

---华软网友回复---
继续期待中

---华软网友回复---
// m_edit=DataArray[5]; 改成
m_edit.Format("%d", DataArray[5]); //一个问题,为什么用double,不用int?

//另外,一些建议,对于你这样有固定格式的文本
//1、首先思量 xml或ini
//2、用CStdioFile,见9楼,能够逐行读取
//3、sscanf(),见12楼,能够一次性猎取所需的3段内容。
---华软网友回复---
bit1=true 18562  
数字有可能为长整形,所以用double
采取12楼能一次读完资料?
---华软网友回复---
建议你用struct,存方便读也方便
---华软网友回复---
引用 25 楼 shaonew 的回复:
bit1=true 18562 
数字有可能为长整形,所以用double
采取12楼能一次读完资料?


//不能一次读完资料,然则能够一次性解析完成一行文字。
---华软网友回复---
// 另外,在VC 32位编译器下,long int(4byte)  = unsigned int(4byte)
---华软网友回复---
搞了快半个月了,还没结果,现在正思量用ini来做
---华软网友回复---
ini 吧,简单又不容易犯错,txt这样判断犯错的可能性照旧对照大 的
---华软网友回复---
GetPrivateProfileString()
GetPrivateProfileInt()
WritePrivateProfileString()
WritePrivateProfileInt()

简单的方法.
P.S 注意,可能中文支持不太好.
---华软网友回复---
這個問題很簡單,先讀取一行存入CString,然后通過匹配字符串"true"或"false"
---华软网友回复---
知道何谓false,何谓true就能够了,换成0和1欠好吗??
---华软网友回复---
用结构就好啊,就用二进制的资料,不要用文本。

也能够思量序列化CArchive。
---华软网友回复---
用ini 配置资料对照方便
---华软网友回复---
引用 12 楼 bobob 的回复:
C/C++ codechar*szBuf="bit1=true 18562";char buf1[32],buf2[32],buf3[32];
    sscanf(szBuf,"%[^=]=%[^ ] %s", buf1,buf2,buf3);


长见识了
---华软网友回复---
承蒙列位大侠指点,问题解决,现在结贴
---华软网友回复---
mark
学习帖,关于这类好贴要留住记号。
---华软网友回复---
学习帖,关于这类好贴要留住记号。      
华软声明:本内容来自网络,如有侵犯您版权请来信指出,本站立即删除。