文件内容替换---郁闷的结果

今天要写一个批量替换文件某一行内容的小程序, 开始的想法是直接在文件里操作(不生成新文件),于是写下如下代码(对单个文件操作) /* string m_strRepSrc;//被替换行中的标识字符串 vc98/include/ string m_strRepDes;//替换成的字符串 F:/Program Files/software/Microsoft Visual Studio 8/VC/include/ 要求效果: "e:/program files/microsoft visual studio/vc98/include/basetsd.h"/ 修改成==> "F:/Program Files/software/Microsoft Visual Studio 8/VC/include/basetsd.h"/ 其中basetsd.h"/要求不变 */ bool CReplace::deal() { //打开文件 CStdioFile hFile(m_strFilePath.c_str(), CFile::modeReadWrite|CFile::shareDenyWrite); //查找 CString strTemp; CString newStr; LONG iIdx = 0; while (hFile.ReadString(strTemp)) { iIdx = strTemp.Find(m_strRepSrc.c_str()); //如果行中含有标识字符串则进入替换 if (iIdx != -1) { //获取不替换部分; newStr = strTemp.Right(strTemp.GetLength() - iIdx - 1 - m_strRepSrc.length()); //basetsd.h"/ //替换成的字符串 newStr = CString(_T("/"")) + CString(m_strRepDes.c_str()) + newStr + CString(_T("/n")); //写回文件 hFile.Seek(-2-strTemp.GetLength(), CFile::current); //找到被替换字符串的起始位置 hFile.WriteString(newStr.GetBuffer()); newStr.ReleaseBuffer(); } } hFile.Close(); return true; } 结果程序一执行,不如人意,由于 "F:/Program Files/software/Microsoft Visual Studio 8/VC/include/basetsd.h"/ 长度要比 "e:/program files/microsoft visual studio/vc98/include/basetsd.h"/ 长 导致文件中"e:/program files/microsoft visual studio/vc98/include/basetsd.h"/后面的内容被覆盖了 之后由于 hFile.Seek(-2-strTemp.GetLength(), CFile::current); hFile.WriteString(newStr.GetBuffer()); 的原因,导致hFile.ReadString读回前面的内容了,从而死循环 并且使目标文件增大了数倍(把前面的内容写进来了)....汗 ====>这里不明白为什么会把文件前面的内容写进来了... 结论:普通方法不能在一个文件里面直接替换文件内容,除非替换与被替换的字符串长度一样 长度一样的话,如下就可以实现 lPos = hFile.GetPosition(); hFile.Seek(-2-strTemp.GetLength(), CFile::current); hFile.WriteString(newStr.GetBuffer()); newStr.ReleaseBuffer(); hFile.Seek(lPos, CFile::begin); 最终,换方法,把文件内容读入内存,在内存中替换文件内容,然后写回文件... 实现如下 //将strBig中所有的strsrc替换成strdst void CReplace::string_replace(string & strBig, const string & strsrc, const string &strdst) { string::size_type pos=0; string::size_type srclen = strsrc.size(); string::size_type dstlen = strdst.size(); while((pos=strBig.find(strsrc, pos)) != string::npos) { strBig.replace(pos, srclen, strdst); //从索引pos开始的srclen个字符替换成后面的strdst pos += dstlen; } } bool CReplace::deal() { ifstream in(m_strFilePath.c_str()); stringstream ss; ss << in.rdbuf(); string s = ss.str(); //size_type类型为unsigned型,与具体机器有关 string::size_type iIdx=0; string::size_type iBegin, iEnd; iIdx = s.find(m_strRepSrc); if (iIdx != string::npos) { iBegin = s.rfind("/"", iIdx); iEnd = iIdx + m_strRepSrc.size(); string sRep = s.substr(iBegin, iEnd-iBegin); //s.replace(sRep, m_strRepDes); string_replace(s, sRep, m_strRepDes); //写回 ofstream out(m_strFilePath.c_str()); out << s; //不需要out.close(),scope结束out析构会自动close() } in.close(); return true; } 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/geeeeeeee/archive/2008/12/12/3506911.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值