2008-09-28 58 views
2

這是簡單的我想出了this question。我並不完全滿意,我認爲這是一個提高我使用STL和基於流編程的機會的機會。幫助改善這個INI解析代碼

std::wifstream file(L"\\Windows\\myini.ini"); 
if (file) 
{ 
    bool section=false; 
    while (!file.eof()) 
    { 
    std::wstring line; 
    std::getline(file, line); 
    if (line.empty()) continue; 

    switch (line[0]) 
    { 
     // new header 
     case L'[': 
     { 
     std::wstring header; 
     size_t pos=line.find(L']'); 
     if (pos!=std::wstring::npos) 
     { 
      header=line.substr(1, pos); 
      if (header==L"Section") 
      section=true; 
      else 
      section=false; 
     } 
     } 
    break; 
     // comments 
     case ';': 
     case ' ': 
     case '#': 
     break; 
     // var=value 
     default: 
     { 
     if (!section) continue; 

// what if the name = value does not have white space? 
// what if the value is enclosed in quotes? 
     std::wstring name, dummy, value; 
     lineStm >> name >> dummy; 
     ws(lineStm); 
     WCHAR _value[256]; 
     lineStm.getline(_value, ELEMENTS(_value)); 
     value=_value; 
     } 
    } 
    } 
} 

你會如何改善這一點?請不要推薦替代庫 - 我只是想從INI文件中解析出一些配置字符串的簡單方法。

回答

3

//如果name = value沒有空格,該怎麼辦?
//如果該值包含在引號內怎麼辦?

我會使用的boost ::正則表達式來匹配每個不同類型的元素,像:

boost::smatch matches; 
boost::regex name_value("(\S+)\s*=\s*(\S+)"); 
if(boost::regex_match(line, matches, name_value)) 
{ 
    name = matches[1]; 
    value = matches[2]; 
} 

正則表達式可能需要一些調整。

我也會用std :: getline替換de stream.getline,擺脫靜態字符數組。

1

此:

for (size_t i=1; i<line.length(); i++) 
     { 
      if (line[i]!=L']') 
      header.push_back(line[i]); 
      else 
      break; 
     } 

應該通過調用簡化爲wstrchr,wcschr,WSTRCHR,還是別的什麼,取決於你是什麼平臺上。

+0

我對此並不滿意 - 那需要通過字符串兩次才能提取出標題名稱。目前的方法是一次通過。 – 2008-09-28 23:37:05

1

//如何將一行代碼轉換爲一個字符串?

使用標準字符串標題中的(非成員)getline函數。