Strings and binary data

This works fine
1
2
3
4
5
6
char* mem; int bnum;
GetFileCont("Capture.PNG", 0, 5000000, mem, bnum);
ofstream out("Capture2.PNG", ios::binary);
out.write(mem, bnum);
out.close();
delete[] mem;

These dont
1
2
3
4
5
6
7
char* mem; int bnum;
GetFileCont("Capture.PNG", 0, 5000000, mem, bnum);
std::string binstring=mem;
delete[] mem;
ofstream out("Capture2.PNG", ios::binary);
out<<binstring;
out.close();

1
2
3
4
5
6
7
8
9
10
char* mem; int bnum;
GetFileCont("Capture.PNG", 0, 5000000, mem, bnum);
std::string binstring=mem;
delete[] mem;
ofstream out("Capture2.PNG", ios::binary);
char* mem2;
strcpy(mem2, binstring.c_str());
out.write(mem2, bnum);
out.close();
delete[] mem2;

GetFileCont stores data from a file in mem and the number of bytes in bnum. Since the first example works, I dont think that function is the source of the problem. What am I doing wrong here?
std::string binstring=mem; looks inappropriate here.
Look at the reference page for std::string operator=
http://www.cplusplus.com/reference/string/string/operator=/

version 2 accepts a parameter const char* s
and the description states that s is a pointer to a null-terminated sequence of characters.

In other words, the operation will copy characters from the address pointed to by s until a null byte is found. Thus it is not suitable for copying binary data, it is only suited to ordinary character strings.

Last edited on
Thank you, that makes sense. What should I use instead to copy the data to a string?

Edit:
1
2
3
4
5
6
7
8
9
std::string binchar2str(char*& data, unsigned int length)
{
std::string retstring="";
for (unsigned int i=0; i<length; i++)
{
retstring+=*(data+i);
}
return retstring;
};
lol
Last edited on
I'm not sure whether there is a good or simple way to do that. You could allocate a string of the required length, and then copy using some method or other from your mem buffer.

But I'm wondering why you want to do this. Is it just an experiment or does it serve some purpose?

If you just wanted to copy a file, then this would be simpler and more efficient:
http://www.cplusplus.com/forum/beginner/132474/#msg712830
Last edited on
Unfortunately I have to use a base64 decode function that takes a std::string as its argument. http://www.adp-gmbh.ch/cpp/common/base64.html

Thanks again though, I didn't know you could do that.
Last edited on
You might use a stringstream - but I don't know whether I've overlooked some pitfall here. I just threw this together as an experiment.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

    using namespace std;

int main()
{
    ifstream fin("Capture.PNG", ios::binary);
    stringstream buffer;
    buffer << fin.rdbuf();
    fin.close();
    if (!fin)
    {
        cout << "fin error" << endl;
    }
    else
    {
        cout << "ok 1\n";
    }
    if (!buffer)
    {
        cout << "buffer error" << endl;        
    }
    else
    {
        cout << "ok 2\n";
    }    
    
    ofstream fout("Capture2.PNG", ios::binary);
    fout << buffer.str(); // write std::string to output
    fout.close();
    if (!fout)
    {
        cout << "fout error" << endl;        
    }
        else
    {
        cout << "ok 3\n";
    }
}

Last edited on
Works perfectly, and its certainly better than my method lol. Thanks Chervil
Alternatively:

1
2
3
4
5
6
7
8
    char* mem; int bnum;
    GetFileCont("Capture.PNG", 0, 5000000, mem, bnum);

    std::string binstring(mem, mem + bnum);
    delete [] mem;

    std::ofstream out("Capture2.PNG", std::ios::binary);
    out << binstring;

Topic archived. No new replies allowed.