0

I want to read file via stdio for RapidXML. I used following:

#include <iostream>
#include <rapidxml.hpp>
#include <stdio.h>
#include <Windows.h>

using namespace rapidxml;

int main(int argc, char** argv)
{
    FILE *pFile;
    pFile = fopen("D:\\ColladaFiles\\sample1.dae", "rb");
    long lSize;
    char *buffer;
    size_t result;

    //if error
    if (pFile == NULL) { fputs("File error", stderr); exit(1); }

    // obtain file size:
    fseek(pFile, 0, SEEK_END);
    lSize = ftell(pFile);
    rewind(pFile);

    // allocate memory to contain the whole file:
    buffer = (char*)malloc(sizeof(char)*lSize);
    if (buffer == NULL) { fputs("Memory error", stderr); exit(2); }

    // copy the file into the buffer:
    result = fread(buffer, 1, lSize, pFile);
    if (result != lSize) { fputs("Reading error", stderr); exit(3); }

    /* the whole file is now loaded in the memory buffer. */

    xml_document<> xdoc;
    xdoc.parse<0>(buffer);

    system("pause");
    return 0;
}

RapidXML generated an error. Because If I write buffer following:

std::cout << buffer << std::endl;

Last line is contains a following: enter image description here How do fast read a file for RapidXML?

Ivan
  • 882
  • 9
  • 20
  • 1
    This is some fiiiiine C++. – ScarletAmaranth Dec 22 '13 at 14:27
  • 1
    @ScarletAmaranth You didn't get the memo? Sarcasm doesn't work on the internet. Especially not in context-less comments. So: spelling it out: this is C, compiled with a C++ compiler. – sehe Dec 22 '13 at 15:09

3 Answers3

0

You missed two things:

  1. on malloc:

    buffer = (char*)malloc(sizeof(char)*lSize + 1); //place for '\0';

  2. after fread:

    buffer[lsize]='\0'; //terminate string

You can also use fgets() or std::ifsteam method getline

SHR
  • 7,149
  • 9
  • 32
  • 50
  • Is std::ifsteam a fast method? I mean, that a streaming methods is slower than c-methods for read. – Ivan Dec 22 '13 at 14:32
  • `std::ifsteam` is a class. `getline` is the method to read with spaces, you can set delimiter to 0 to read all from text file. it is more c++ then fread/fgets which are c methods. also you can use `new` instead of `malloc`, `delete` instead of `free` (by the way: you missed the free), and so on. if you want to go further, you can also read directly to std::string. – SHR Dec 22 '13 at 14:36
  • look here at the first answer for the best way to do it: http://stackoverflow.com/questions/2602013/read-whole-ascii-file-into-c-stdstring – SHR Dec 22 '13 at 14:40
0

The following line expects char array with null termination character(‘\0') at the end of the array.

xdoc.parse<0>(buffer);

So add following lin after reading file, and also allocate space for that '\0’.

buffer[lSize]='\0
dg_no_9
  • 914
  • 1
  • 8
  • 24
0

For C++ you shouldn't be reading the file that way. See this question. Read whole ASCII file into C++ std::string

Basically, Try this instead.

std::ifstream t("D:\\ColladaFiles\\sample1.dae"); 
std::stringstream buffer; 

buffer << t.rdbuf(); //read file into stringstream

xdoc.parse<0>(buffer.str().c_str()); // parse it
Community
  • 1
  • 1
Roddy
  • 63,052
  • 38
  • 156
  • 264