C ++ c_str does not return whole string

I have tried the following code with both regular ifstreams and current boost: the iostream I am using has the same result.

It is intended to load a file from physfs into memory and then pass it to a handler for processing (for example, images, audio or data). Currently, when c_str is called, it only returns a small portion of the file.

        PhysFS::FileStream file("Resources/test.png" , PhysFS::OM_READ);

    if(file.is_open()) {

        String* theFile;

        theFile = new String((std::istreambuf_iterator<char>(file)), 
        std::istreambuf_iterator<char>());

        String::iterator it;
        for ( it=theFile->begin() ; it < theFile->end(); it++ ) {
            std::cout << *it; 
        } // Outputs the entire file

        std::cout << theFile->c_str(); // Outputs only the first few lines

    }

      

The iterator loop outputs the entire png file as expected, but the call to c_str only returns the first few characters (\ 211PNG).

I've tested variations of this code quite often without any success. Any ideas?

+2


source to share


3 answers


I am assuming the next character is a null (ASCII 0) byte. c_str () just gives you * char, so your entry to stdout is interpreted as a class C string that ends at the first zero byte.

If you really want a C-like interface for this string, the main thing is that theFile-> c_str () points to your data, and theFile.length gives you the number of characters in the string. Therefore, you can do something like this:



char *c_value = theFile->c_str()
for (int i = 0; i < theFile.length; i++)
{
   cout << c_value[i];
}

      

The real solution depends on why you are converting to char * in the first place. If you are calling an inherited function that only takes char *, there will probably be a length argument to that inherited function as well.

+15


source


One of the bytes is probably 0. This means the end of the line for cout when passing a char * (which is c_str)



+2


source


I would like to use for this std::vector<unsigned char>

instead std::string

. It is much easier to deal with binary data in a vector. You can refer to the base pointer using &vec[0]

if you need C-style array access. I would also like to make sure your file abstraction is using std::ios_base::binary

for file mode under the hood.

+2


source







All Articles