Я бы подошел к этому так:
- Создать класс, который представляет пару имя-значение
- Использование
std::istream& operator>>( std::istream &, NameValuePair & );
Затем вы можете сделать что-то вроде:
ifstream inifile( fileName );
NameValuePair myPair;
while( ifstream >> myPair )
{
myConfigMap.insert( myPair.asStdPair() );
}
Если ваш INI-файл содержит разделы, каждый из которых содержит пару имен-значений, то вам необходимо выполнить чтение до конца раздела, чтобы ваша логика не использовала сбой потока, а использовала бы некую абстрактную фабрику с состоянием машина. (Вы читаете что-то, а затем определяете, что именно так определяет ваше состояние).
Что касается реализации потока, считываемого в вашу пару имя-значение, то это можно сделать с помощью getline, используя кавычку в качестве терминатора.
std::istream& operator>>( std::istream& is, NameValuePair & nvPair )
{
std::string line;
if( std::getline( is, line, '\"' ) )
{
// we have token up to first quote. Strip off the = at the end plus any whitespace before it
std::string name = parseKey( line );
if( std::getline( is, line, '\"' ) ) // read to the next quote.
{
// no need to parse line it will already be value unless you allow escape sequences
nvPair.name = name;
nvPair.value = line;
}
}
return is;
}
Обратите внимание, что я не записывал в nvPair.name, пока мы полностью не проанализировали токен. Если потоковая передача не удалась, мы не хотим частично писать.
Поток останется в состоянии сбоя, если какой-либо из getline завершился с ошибкой. Это произойдет естественным образом в конце файла. Мы не хотим генерировать исключение, если оно не выполняется по этой причине, поскольку это неправильный способ обработки конца файла. Вы можете бросить, если произойдет сбой между именем и значением, или если у имени нет знака завершающего = (но не пустого), потому что это не является естественным явлением.
Обратите внимание, что это позволяет пробелы и даже переводы строк между кавычками. Все, что находится между ними, читается иначе, чем другие цитаты. Вы должны будете использовать escape-последовательность, чтобы разрешить их (и проанализировать значение).
Если вы использовали \ "в качестве escape-последовательности, тогда, когда вы получите значение, вы должны" зациклить ", если оно заканчивается на \ (а также заменить его на кавычку), и объединить их вместе.