6

So I'm using this code to write the file(just testing now, I'm going to write a level editor later):

 
int main()
{
    ofstream file("level.bin", ios::binary);
    int ents = 1; //number of entites
    file.write((char*)&ents, sizeof(int));
    float x = 300; //x and y coords
    float y = 500;
    file.write((char*)&x, sizeof(float));
    file.write((char*)&y, sizeof(float));
    int imglength = 12; //strings are prefixed by a length
    file.write((char*)&imglength, sizeof(int));
    string img = "platform.png"; //string
    file.write(img.c_str(), sizeof(img.c_str()));
    cout << "wrote\n";
    return 0;
}

The code I'm using to load it is this:

 

void SceneManager::LoadScene(std::string filename) { std::ifstream file(filename.c_str(), std::ios::binary); int ents; file.read((char*)&ents, sizeof(int)); std::cout << ents << std::endl; for(int i = 0; i < ents; i++) { //read x and y coords float x; float y; file.read((char*)&x, sizeof(float)); file.read((char*)&y, sizeof(float)); std::cout << x << " " << y << std::endl; int imglength; file.read((char*)&imglength, sizeof(int)); std::cout << imglength << std::endl; std::stringstream ss; for(int k = 0; k <= imglength; k++) { //read string char c; file.read((char*)&c, sizeof(char)); ss << c; } std::string image = ss.str(); std::cout << image << std::endl; phys_static ent; Def edef; edef.SetVal("x", x); edef.SetVal("y", y); edef.SetString("image", image); ent.init(edef); AddEntity(ent); } file.close(); }

Everything works fine except the string loading. I expect I'm writing it wrong, as instead of the platform.png it shows plattttttttt and errors out when I load the image. I'm also prefixing the string with it's length. What is the correct way to write a string to a binary file? What is the corre

0

1 Answer 1

10

The error is at this line:

file.write(img.c_str(), sizeof(img.c_str()));

What you want is:

file.write(img.c_str(), img.size());

The sizeof(img.c_str()) returns 4 because sizeof(char *) (the return type of c_str()) is 4 on your platform. This means first 4 characters are written and then you get just some garbage.

Sign up to request clarification or add additional context in comments.

6 Comments

That worked, except it added an extra g on the end of the string for some odd reason. I'll try decreasing the size to 11 and see if that does anything.
Null chars should not be a problem for the OP’s code (with your correction). It never assumes that '\0' acts as a string terminator and it never uses C style strings.
@Chris: Ah yes, that's because there should be < imglength in the for-loop reading the string - you are counting from zero.
@Konrad: It does assume that in the c_str() part. If img contained some '\0' characters, c_str() might return a shorter string (depending on the implementation of c_str()). But generally it should be safe because all the implementations I've seen just return the internal char buffer.
@dark It doesn’t. The c_str just creates a pointer to the characters (&img[0] would also have worked). The number of bytes to write is solely determined by the second parameter to write – whether there’d a null char in the first argument is irrelevant. Also, c_str must not return a shorter string. It must return a pointer to a char array that contains the whole string (see §21.3.6.1), plus null termination.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.