-
April 9th, 2019, 03:30 PM
#1
rapidxml
Hello,
i am trying to load and read a xml file using radipxml. Here is the code:
Interface.h:
Code:
#include "../DataIO/Input.h"
class CInterface{
public:
void GetInput();
protected:
// To define a pointer to other class
CInput *pInput;
};
Interface.cpp:
Code:
#include <cstdio>
#include <cstring>
#include "../DataIO/Input.h" // Where Class CInput for xml file is defined
#include "Interface.h"
//Function to obtain the input data from xml file.
// Call the Input.cpp file and his functions
void CInterface::GetInput(){
//To define a pointer to file
FILE *pFile;
const char* filename;
filename = "C:/Development/Test/Input.hun";
pFile = fopen(filename, "rt");
if (pFile == NULL){
puts("Couldn't open file");
exit(0);
}
// Call the Input.cpp file and his functions through the pointer
pInput->load(pFile);
pInput->getInfo();
}
Input.h:
Code:
class CInput {
private:
xml_document<> doc; // character type defaults to char
vector<char> buffer;
public:
// Definition of the function to get the data from InputFile
void load(FILE *pFile);
};
Input.cpp:
Code:
#include "rapidxml_utils.hpp"
#include "Input.h"
using namespace std;
using namespace rapidxml;
/**
Load the xml document
make a safe-to-modify copy of input_xml
*/
void CInput::load(FILE *pFile){
ifstream file("Input.hun");
/* "Read file into vector<char>" */
vector<char> buffer((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
buffer.push_back('\0');
doc.parse<0>(&buffer[0]); // 0 means default parse flags
}
The program builds without errors. But when debugging an Exception thrown: read access violation in function load. How can I solve the access violation?
Thanks
Last edited by 2kaud; April 10th, 2019 at 03:41 AM.
Reason: Cleaned up code tags
-
April 10th, 2019, 01:42 AM
#2
Re: rapidxml
What line of your code produces this error?
Victor Nijegorodov
-
April 10th, 2019, 02:31 AM
#3
Re: rapidxml
I guess you need to decide who is actually responsible for opening the file.
Code:
filename = "C:/Development/Test/Input.hun";
pFile = fopen(filename, "rt");
// Call the Input.cpp file and his functions through the pointer
pInput->load(pFile);
Then later
Code:
void CInput::load(FILE *pFile){
ifstream file("Input.hun");
1. I'm guessing the 2nd attempt to open the file barfs, because you've already opened it.
2. You're not even using your pFile parameter anyway.
-
April 10th, 2019, 02:37 PM
#4
Re: rapidxml
Originally Posted by VictorN
What line of your code produces this error?
The line that produces the error is
Code:
doc.parse<0>(&buffer[0]);
-
April 10th, 2019, 04:37 PM
#5
Re: rapidxml
I suspect that the file hasn't been read because it hasn't been opened properly, so buffer initialisation using istreambuff_iterator fails so buffer is empty and has no elements (just the extra \0 added) and hence doc.parse() fails because it's trying to access elements in the vector which aren't present.
After the ifstream statement, check that file is actually opened. After the vector statement, check that the size of buffer isn't 0. Note that the filename in GetInput() and Load() are different (load has no paths specified).
When you do something like open a file, read, call a function etc etc you should always check that the expected operation has been carried out properly with no errors.
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 11th, 2019, 04:21 AM
#6
Re: rapidxml
Originally Posted by 2kaud
After the ifstream statement, check that file is actually opened. After the vector statement, check that the size of buffer isn't 0. Note that the filename in GetInput() and Load() are different (load has no paths specified).
I have check if the file was opened and it was not opened. For that I changed my load function as:
Code:
void CInput::load(FILE *pFile){
ifstream file(pFile);
/* "Read file into vector<char>" */
vector<char> buffer((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
buffer.push_back('\0');
doc.parse<0>(&buffer[0]); // 0 means default parse flags
}
Now the vector is not 0. And the file is opened in the GetInput function.
I become again in the last line the same exception as above.
-
April 12th, 2019, 04:29 AM
#7
Re: rapidxml
Generally templates take types, not values. Should doc.parse<0>(&buffer[0]); be doc.parse<string>(&buffer[0]); or some other type instead?
-
April 15th, 2019, 04:19 AM
#8
Re: rapidxml
Originally Posted by salem_c
I guess you need to decide who is actually responsible for opening the file.
I have decided to open the file in the function load. My GetInput and load function are now as follows:
Code:
void CInterface::GetInput(){
char *fullpath;
fullpath = "C:/Development/Test/Input.hun";
pInput->load(fullpath);
pInput->getInfo();
}
void CInput::load(char *fullpath){
ifstream file(fullpath);
if (!file){
puts("Couldn't open file");
exit(0);
}
/* "Read file into vector<char>" */
vector<char> buffer((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
buffer.push_back('\0');
doc.parse<0>(&buffer[0]); // 0 means default parse flags
}
Originally Posted by Arjay
Generally templates take types, not values. Should doc.parse<0>(&buffer[0]); be doc.parse<string>(&buffer[0]); or some other type instead?
I am not an expertise of rapidxml, I take the line
Code:
doc.parse<0>(&buffer[0]);
from the documentation at http://rapidxml.sourceforge.net/manual.html
I think the problem for the exception comes from
Code:
vector<char> buffer((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
but until now I have not solved the problem. Any suggestion?
Last edited by laephy; April 24th, 2019 at 04:39 AM.
-
April 15th, 2019, 06:34 AM
#9
Re: rapidxml
Code:
vector<char> buffer((istreambuf_iterator<char>(wathunfile)), istreambuf_iterator<char>());
That isn't the same as post #8. You should know exactly which line in your program causes the exception. Use the debugger to trace through the code and find out where the exception occurs.
PS shouldn't istreambuf_iterator be istream_iterator?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 15th, 2019, 08:13 AM
#10
Re: rapidxml
You can use a back_inserter to read the file in the method you are using.
I would open in binary mode.
Code:
void CInput::load(char *fullpath)
{
ifstream file(fullpath,ios::binary); // open binary
if (!file)
{
puts("Couldn't open file");
exit(0);
}
/* "Read file into vector<char>" */
vector<char> buffer;
std::copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(buffer));
buffer.push_back('\0');
doc.parse<0>(&buffer[0]); // 0 means default parse flags
}
The above code might be a little slow for a large file. Another method is to get the
size of the file and resize the vector to that size.
Code:
void CInput::load(char *fullpath)
{
ifstream file(fullpath, ios::binary); // open binary
if (!file)
{
puts("Couldn't open file");
exit(0);
}
file.seekg(0, std::ios_base::end);
std::streampos fileSize = file.tellg();
file.seekg(0, std::ios_base::beg);
size_t buffer_size = size_t(fileSize) + 1; // +1 for the '\0'
vector<char> buffer;
buffer.resize(buffer_size);
/* "Read file into vector<char>" */
file.read(&buffer[0], buffer_size);
buffer[buffer_size - 1] = '\0';
doc.parse<0>(&buffer[0]); // 0 means default parse flags
}
-
April 15th, 2019, 08:43 AM
#11
Re: rapidxml
From the RapidXml documentation:
"The following code causes RapidXml to parse a zero-terminated string named text: "
Your buffer is not a string, but a vector<char>. You may need:
Code:
string buffer ((istream_iterator<char>(file)), istream_iterator<char>());
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
April 16th, 2019, 06:49 AM
#12
Re: rapidxml
Just a note: By default, using istream_iterator<char> will throw out whitespaces, which might not be wanted:
Example, if the file contains:
Code:
<message>Hello World</message>
the string will end up with:
Code:
<message>HelloWorld</message>
-
April 24th, 2019, 04:34 AM
#13
Re: rapidxml
I have eliminate the exception in function load as follows
Code:
void CInput::load(char *fullpath){
ifstream file(fullpath);
if (!file){
puts("Couldn't open file");
exit(0);
}
/* "Read file into vector<char>" */
vector<char> buffer;
buffer.assign((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());
buffer.push_back('\0');
// only use xml_copy from here on!
xml_document<> doc;
// we are choosing to parse the XML declaration
// parse_no_data_nodes prevents RapidXML from using the somewhat surprising
// behavior of having both values and data nodes, and having data nodes take
// precedence over values when printing
// >>> note that this will skip parsing of CDATA nodes <<<
doc.parse<parse_declaration_node | parse_no_data_nodes>(&buffer[0]);
}
unfortunately now the program crash when the following line is executed.
Code:
doc.parse<parse_declaration_node | parse_no_data_nodes>(&buffer[0]);
In particular when the function parse is executed during parse and append new child where text before crash is /Project>. It is possible that the problem comes from my xml file? or comes from the load function?
Last edited by laephy; April 24th, 2019 at 04:38 AM.
-
April 24th, 2019, 06:25 AM
#14
Re: rapidxml
What debugging of the rapidxml code have you done? Have you traced into the code to see what is happening and why an exception is caused? RapidXML is a set of .hpp header c++ files, so the source is available. Have you tried asking the question on the RapidXML discussion forum?
All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!
C++23 Compiler: Microsoft VS2022 (17.6.5)
-
May 1st, 2019, 02:38 PM
#15
Re: rapidxml
Originally Posted by laephy
In particular when the function parse is executed during parse and append new child where text before crash is /Project>. It is possible that the problem comes from my xml file? or comes from the load function?
The problem was at the xml file. I forgot to close a child. Now the code compile and load the xml without problem. Thanks
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|