5

I use the function below "writeFileBytes" to write the contents of a std::vector<unsigned char> to a file. I want to use the type "unsigned char" to save the file (note that is made a cast for "char"). The reason for that question is because "unsigned char" has compatibility with any byte ("00000000" bits, for example). When we use "char" we have some problems with the manipulation of certain "invalid" chars.

See this topic What is the most suitable type of vector to keep the bytes of a file? for more information about the issues with "00000000" bits (1 byte).

void writeFileBytes(const char* filename, std::vector<unsigned char>& fileBytes){
    std::ofstream file(filename, std::ios::out|std::ios::binary);
    file.write(fileBytes.size() ? (char*)&fileBytes[0] : 0, 
               std::streamsize(fileBytes.size()));
}

writeFileBytes("xz.bin", fileBytesOutput);

Is there a way to use the type "unsigned char" natively to write to a file?

This concern really make sense?


UPDATE I:

Is there a way to use the type "unsigned char" natively to write to a file? -> YES!

Following the krzaq's guidelines!

void writeFileBytes(const char* filename, std::vector<unsigned char>& fileBytes){
    std::ofstream file(filename, std::ios::out|std::ios::binary);
    std::copy(fileBytes.cbegin(), fileBytes.cend(),
        std::ostream_iterator<unsigned char>(file));
}

UPDATE II:

This concern really make sense? -> In some ways, YES!

As I comment below...

"...'unsigned char' seems to have a 'higher level of compatibility' (include '00000000' bits). When we try to convert these 8 bits ('00000000' bits) to 'char' we have no value unlike 'unsigned char'. With 'unsigned char' we have an invalid/unrecognized 'char' value, but we have..."

See this topic What is the most suitable type of vector to keep the bytes of a file? for more information!

Community
  • 1
  • 1
Eduardo Lucio
  • 1,771
  • 2
  • 25
  • 43
  • It's so good for the community and who enriches it (like me) when a negative comes accompanied by an explanation or reason. In this way we can improve things together! If there is something wrong I can fix or delete this thread. I'm sure that we are reasonable people. – Eduardo Lucio Oct 16 '16 at 15:44
  • "00000000" bits (1 byte) is not recognizable by the type "char". When we try to convert these 8 bits to "char" we have no value unlike "unsigned char". With "unsigned char" we have an invalid/unrecognized "char" value, but we have. I suggest taking a look at all this discussion in http://stackoverflow.com/questions/40052857/c-save-the-contents-of-a-stdvectorunsigned-char-to-a-file/40052889#40052889. Thanks! – Eduardo Lucio Oct 16 '16 at 15:52

1 Answers1

5

It doesn't matter, char* can be used to access any kind of data and it'll work correctly. But if you don't want to use the explicit cast, maybe use std::copy and std::ostreambuf_iterator:

copy(fileBytes.cbegin(), fileBytes.cend(),
     ostreambuf_iterator<char>(file));

alternatively, you can call

copy(fileBytes.cbegin(), fileBytes.cend(),
     ostream_iterator<char>(file));

But it will do the same thing, only possibly slower.

Btw: you can't pass a null pointer to write, that's UB.

krzaq
  • 16,240
  • 4
  • 46
  • 61
  • I agree with you. But as we can see in this thread http://stackoverflow.com/questions/40052857/c-save-the-contents-of-a-stdvectorunsigned-char-to-a-file/40052889#40052889, "unsigned char" seems to have a "higher level of compatibility" (include "00000000" bits). When we try to convert these 8 bits ("00000000" bits) to "char" we have no value unlike "unsigned char". With "unsigned char" we have an invalid/unrecognized "char" value, but we have. Thanks! – Eduardo Lucio Oct 16 '16 at 15:57
  • I'm having the following error: "error: no matching function for call to ‘std::ostreambuf_iterator::ostreambuf_iterator(std::ofstream&)’". Ideas? These are the code includes: #include , #include , #include , #include , #include , #include , #include , #include , #include , #include , #include , #include – Eduardo Lucio Oct 18 '16 at 15:12
  • @EduardoLucio try `ostreambuf_iterator(file)` instead. – krzaq Oct 18 '16 at 15:17
  • 1
    @EduardoLucio alternatively you can use `ostream_iterator(file)` (no `buf`). For `char`s it shouldn't matter all that much – krzaq Oct 18 '16 at 15:19
  • "ostream_iterator(file)" worked perfectly! You are the man! Thanks! – Eduardo Lucio Oct 18 '16 at 15:44