帮助改善此INI解析代码
时间:2020-03-06 14:51:17 来源:igfitidea点击:
这是我想出的简单问题。我对它并不完全满意,我把它看作是一个机会,可以帮助改善我对STL和基于流的编程的使用。
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文件中解析出一些配置字符串。
解决方案
这:
for (size_t i=1; i<line.length(); i++) { if (line[i]!=L']') header.push_back(line[i]); else break; }
应该通过调用wstrchr,wcschr,WSTRCHR或者其他方式简化操作,具体取决于我们所使用的平台。
// how to get a line into a string in one go?
使用标准字符串标题中的(非成员)getline函数。
// what if the name = value does not have white space? // what if the value is enclosed in quotes?
我将使用boost :: regex来匹配每种不同类型的元素,例如:
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,摆脱了静态char数组。