私はC ++を初めて使用します。セクションとキーと値のペアを持つiniファイルを読みたいです。セクションによっては、対応するキーの値を読み取りたい。主に、角括弧で囲まれたセクションを読みたいと思います。助けてください。ありがとうございました。
2 に答える
2
実際の INI ファイルの解析には、iniparser ライブラリを強くお勧めします。文書化されており、CおよびC++ プログラムの両方で簡単に使用できます。
形式の文字列の解析のみに関心がある場合[Section name]
は、次のようにすることができます: 文字列の最初の '[' と最後の ']' を見つけて、位置をマークします。両方の文字が見つかった場合は、セクション名を特定した位置の間の部分文字列にします。
を使用していると仮定するとstd::string
、次のことができます。
std::string myString = " [Section name] ";
std::size_t start = myString.find_first_of( '[' );
std::size_t end = myString.find_last_of( ']' );
std::string sectionName;
if( start != std::string::npos && end != std::string::npos )
{
sectionName = myString.substr(start + 1, end - 1);
}
std::cout << sectionName << std::endl;
于 2012-06-06T06:57:38.320 に答える
0
このスニペットは、ini ファイルを解析して # または ; をスキップするための基本的なロジックを示しているはずです。コメントとして扱われる接頭辞付きの行
これには、グループ名、名前、および値の健全性チェックが必要ですが、デモンストレーションとしては十分です。
#include <iostream>
#include <string>
#include <map>
//
// a simple ini file parser (doesn't check for validity of name field length wise or if it has = char
// to demonstrate basic parsing
//
class IniFile
{
public:
enum { MAX_LINE_LEN = 10*1024 };
class MalformedInputException : public std::exception
{
public:
const char* what() const throw() { return "Input is not a valid or well formed ini file"; }
};
typedef std::map<std::string, std::string> Properties;
IniFile(){}
virtual ~IniFile(){}
std::istream& load(std::istream& in)
{
char lineBuffer[MAX_LINE_LEN];
std::string curGroup = "";
while(!in.eof())
{
in.getline(lineBuffer, MAX_LINE_LEN);
//std::cout<<"line buffer : {"<<lineBuffer<<"}"<<std::endl;
std::string line = trim(lineBuffer);
//std::cout<<"trimmed : {"<<line<<"}"<<std::endl;
// we process only non-empty / non-comment lines
if(line.size() > 0 && line[0] != '#' && line[0] != ';')
{
if(line[0] == '[' && line[line.size() - 1] == ']')
{
curGroup = trim(line.substr(1, line.size() - 2));
}
else if(curGroup.size() > 0)
{
size_t index = line.find_first_of('=');
//todo: needs checks for valid name=value format here
Properties& props = m_props[curGroup]; // this will create new Properties if none exists
props[line.substr(0,index)] = line.substr(index+1);
}
else
{
throw MalformedInputException();
}
}
}
return in;
}
std::ostream& save(std::ostream& os) const
{
std::map<std::string, Properties>::const_iterator iter = m_props.begin();
while(iter != m_props.end())
{
os<<"["<<iter->first<<"]"<<std::endl;
Properties::const_iterator propIter = iter->second.begin();
while(propIter != iter->second.end())
{
os<<propIter->first<<"="<<propIter->second<<std::endl;
propIter++;
}
iter++;
}
return os;
}
std::string trim(const std::string& input)
{
static std::string WHITESPACES = "\r\n \t\b\a";
if(input.size() == 0){ return input; }
else
{
size_t start = 0;
for(size_t index = 0; index < input.size(); index++)
{
if(WHITESPACES.find(input[index]) < WHITESPACES.size())
{
start = index;
}
else
{
break;
}
}
size_t endIndex = input.size() - 1;
if(start == endIndex){ return ""; }
for(; endIndex > start; endIndex--)
{
char c = input.at(endIndex);
if(WHITESPACES.find_first_of(c) >= WHITESPACES.size())
{
break;
}
}
size_t length = endIndex - start + 1;
return input.substr(start, length);
}
}
private:
std::map<std::string, Properties> m_props;
};
inline std::ostream& operator << (std::ostream& os, const IniFile& iniFile)
{
return iniFile.save(os);
}
inline std::istream& operator >> (std::istream& in, IniFile& iniFile)
{
return iniFile.load(in);
}
#include <sstream>
int main(int argc, char** argv)
{
std::ostringstream ss;
ss<<"# sample ini file"<<std::endl;
ss<<"[Group1]"<<std::endl;
ss<<"foo=bar \n"<<std::endl;
ss<<"baz=foz"<<std::endl;
ss<<"; this is another comment"<<std::endl;
ss<<"[Group2]"<<std::endl;
ss<<"blanga=kukoo"<<std::endl;
std::string buf = ss.str();
std::istringstream sin(buf);
IniFile iniFile;
iniFile.load(sin);
iniFile.save(std::cout<<"Ini File Loaded : "<<std::endl);
return 0;
}
于 2012-06-06T07:35:52.067 に答える