В чем разница между этими двумя методами чтения входного файла?
1) Использование 'ifstream.get()'
и
2) Использование vector<char>
с ifstreambuf_iterator<char>
(менее понятным для меня!)
(кроме очевидного ответа о наличии изящных векторных методов для работы)
Входной файл - XML, и, как вы видите ниже, сразу же анализируетсяв документ rapidxml.(инициализирован в другом месте, см. пример основной функции.)
Сначала позвольте мне показать вам два способа написания функции load_config, один из которых использует ifstream.get()
, а другой - vector<char>
Метод1 ifstream.get()
предоставляет рабочий код и безопасный объект документа rapidXML:
rapidxml::xml_document<> *load_config(rapidxml::xml_document<> *doc){
ifstream myfile("inputfile");
//read in config file
char ch;
char buffer[65536];
size_t chars_read = 0;
while(myfile.get(ch) && (chars_read < 65535)){
buffer[chars_read++] = ch;
}
buffer[chars_read++] = '\0';
cout<<"clearing old doc"<<endl;
doc->clear();
doc->parse<0>(buffer);
//debug returns as expected here
cout << "load_config: Name of my first node is: " << doc->first_node()->name() << "\n";
return doc;
}
Метод 2 приводит к закрытому документу rapidXML другой библиотекой, в частности, к вызову curl_global_init (CURL_GLOBAL_SSL) [см. Основной код ниже] - но я пока не виню его за curl_global_init.
rapidxml::xml_document<> *load_config(rapidxml::xml_document<> *doc){
ifstream myfile("inputfile");
vector<char> buffer((istreambuf_iterator<char>(inputfile)),
istreambuf_iterator<char>( ));
buffer.push_back('\0');
cout<<"file looks like:"<<endl; //looks fine
cout<<&buffer[0]<<endl;
cout<<"clearing old doc"<<endl;
doc->clear();
doc->parse<0>(&buffer[0]);
//debug prints as expected
cout << "load_config: Name of my first node is: " << doc->first_node()->name() << "\n";
return doc;
}
основной код:
int main(void){
rapidxml::xml_document *doc;
doc = new rapidxml::xml_document;
load_config(doc);
// this works fine:
cout << "Name of my first node is: " << doc->first_node()->name() << "\n";
curl_global_init(CURL_GLOBAL_SSL); //Docs say do this first.
// debug broken object instance:
// note a trashed 'doc' here if using vector<char> method
// - seems to be because of above line... name is NULL
// and other nodes are now NULL
// causing segfaults down stream.
cout << "Name of my first node is: " << doc->first_node()->name() << "\n";
Я чертовски уверен, что все это выполняется в одном потоке, номожет быть, что-то происходит за пределами моего понимания.
Я также беспокоюсь, что исправил только симптом, а не причину ..., просто изменив функцию загрузки файлов.Обращаясь к сообществу за помощью здесь!
Вопрос: Почему бы отойти от вектора к массиву символов исправить это?
Подсказка: я знаю, что rapidXML использует некоторое умное управление памятью, котороефактически напрямую обращается к входной строке.
Подсказка: основная функция выше создает динамический (новый) xml_document.Этого не было в исходном коде, и это артефакт отладочных изменений.Исходный (ошибочный) код объявил его и не выделил его динамически, но возникли идентичные проблемы.
Еще один совет для полного раскрытия (хотя я не понимаю, почему это важно) - есть еще один экземпляр векторав этом беспорядке кода, который заполняется данными в объекте rapidxml :: xml_document.