Как прочитать слово между "" и ifstream? - PullRequest
0 голосов
/ 18 ноября 2010

INI-файл, который содержит: address = "localhost" username = "root" password = "yourpassword" database = "yourdatabasename"

и мне нужно найти слово между двумя "" с помощью ifstreamположить его в символ.

Есть ли способ сделать это ??

Ответы [ 2 ]

0 голосов
/ 19 ноября 2010

Я бы подошел к этому так:

  • Создать класс, который представляет пару имя-значение
  • Использование 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-последовательности, тогда, когда вы получите значение, вы должны" зациклить ", если оно заканчивается на \ (а также заменить его на кавычку), и объединить их вместе.

0 голосов
/ 18 ноября 2010

Если между каждой парой есть новые строки, вы можете сделать следующее.

std::string line; //string holding the result
char charString[256]; // C-string

while(getline(fs,line)){ //while there are lines, loop, fs is your ifstream
    for(int i =0; i< line.length(); i++) {
        if(line[i] != '"') continue; //seach until the first " is found

        int index = 0;
        for(int j= i+1; line[j] != '"'; j++) {
            charString[index++] = line[j];
        }
        charString[index] = '\0'; //c-string, must be null terminated

        //do something with the result
        std::cout << "Result : " << charString << std::endl;

        break; // exit the for loop, next string
    }
}
...