保存文件中的更改

时间:2012-03-09 13:49:40

标签: c++

Ojective:要打开配置文件,请查找包含标记并更改其值的特定行

示例:

    config .txt    
    bla bla    
    bla bla   
    SYSTEM_A_EXTERNAL_IP=192.168.0.57  // need to change ip address    
    bla bla   
    bla bla 

到目前为止我做了什么:我的代码打开文件并查找具有标记的特定行并更改其值。

问题:我未能在实际文件中看到这些更改。我知道ofstream会写入行,但如果我使用ofstream而不是ifstream getline函数会出错。

代码1:

bool SetIpAddr(string & iAddr)    
{     
    bool check= false;    

    // Open  file    
    ifstream  iFile(IpConfigFile.c_str(), ios_base::out|ios::app | ios::binary);
    if(iFile.is_open())    
    {    
        check= true;    
    }          

    // Read content of ipconf file searching for the value of Head Id Name
    if(true == check)
    {
        string TargetName = SystemAIdValue + ExternalIpNamePostfix+ ValueAssignmentCharacter;
        string outbuf;
        while( !iFile.eof() )
        {
            getline(iFile, outbuf);    

            // find the matching string     
            if( 0 == outbuf.compare(0,TargetName.size(),TargetName) )
            {
            outbuf.erase(outbuf.begin()+TargetName.size(), outbuf.end());    
            outbuf.insert(0+TargetName.size(), iAddr);
                std::cout<< " after insertion  " << outbuf << std::endl;
                break;
            }
        }
    }
    // Close  (input) file
    if( iFile.is_open() )
    {
        iFile.close();
    }
    return check; 
}

Code2:也无效。

 bool SetIpAddr(string & aIpAddr)
 {
     bool lResult = false;    
     std::fstream  ifile("platform_ip_config");      
     string lTargetIp = HeadAIdValue + ExternalIpNamePostfix+ ValueAssignmentCharacter;
     std::deque<std::string>lines;
     std::string inbuf;
     while( std::getline(ifile, inbuf));
     {
         std::cout<<" we are in while"<<std::endl;
         std::cout<<" getline =="<< inbuf<< std::endl;
         std::cout<<" ip =="<<lTargetIp<< std::endl;
         if( 0 == inbuf.compare(0,lTargetIp.size(),lTargetIp) )
         {
             std::cout<<" we are in matching"<<std::endl;            
             std::cout<< inbuf << std::endl;
         inbuf.erase(inbuf.begin()+lTargetIp.size(), inbuf.end());
             std::cout<<" after erase " << inbuf << std::endl;
         inbuf.insert(0+lTargetIp.size(), aIpAddr);
             std::cout<< " after insertinon  " << inbuf << std::endl;        
         }
         lines.push_back(inbuf);
     } 
     ifile.seekg (0, ios::beg );
     std::copy(lines.begin(), lines.end(), 
     std::ostream_iterator<std::string>(ifile, "\n"));
  }
  lines.push_back(inbuf);
}
ifile.seekg (0, ios::beg );
std::copy(lines.begin(), lines.end(), 
std::ostream_iterator<std::string>(ifile, "\n"));
}

2 个答案:

答案 0 :(得分:1)

使用ifstream打开文件进行读取,如果使用fstream基类,则应该可以修改文件

另一种方法是将整个文件读入缓冲区,更改缓冲区并使用ofstream类覆盖原始文件

答案 1 :(得分:1)

你正在做的事情本质上是棘手的,写到文件的中间希望结果保持不变。

例如

192.168.120.111 

消耗的字符多于

10.10.10.10

我这样做的方法是将整个文件读成行。

std::fstream file(file_name);
std::deque<std::string> lines;
std::string temp;
while(std::getline(file, temp))
{
    //detect that this the line you want
    if(this_is_my_line(temp)) 
    {
         //do what you need to do to the string
         modify(temp);
    }

    lines.push_back(temp);
}
file.seekg (0, ios::beg
//write back to file
std::copy(lines.begin(), lines.end(), 
          std::ostream_iterator<std::string>(file, "\n"));

请注意,您不需要在C ++中显式关闭文件,RAII语义将为您关闭它,通过自己动手,您可以增加错误进入代码的机会。

这适用于我的系统

#include <iostream>
#include <fstream>
#include <string>
#include <deque>
#include <iterator>
int main()
{
    std::string line;
    const std::string token("SYSTEM_A_EXTERNAL_IP=");
    std::deque<std::string> lines;
    {
        std::ifstream file("config.txt");
        while(std::getline(file, line))
        {
            if(std::equal(token.begin(), token.end(), line.begin()))
            {
                line=token+"10.10.10.5"; //or whatever
            }
            lines.push_back(line);
        }
    }
    {
        std::ofstream file("config.txt");
        std::copy(lines.begin(), lines.end(),
             std::ostream_iterator<std::string>(file,"\n"));
    }
    return 0;
}