Hello!

Please help me with this thing: I have an array of chars of zeros ('0') and ones ('1'), I need to write it into a binary file in a packed form, i.e. so that each element would occupy one bit.

I read a lot about it, but unfortunately, nothing happens.

void OutputResult1(char **Result) { (*Result) = new char[1000]; for (int i = 0; i < 1000 ;i++) { (*Result)[i] = 0; } int l = 0; for ( int i = 0; i<MyText.size(); i++) { while ( MyText[i] != W[l]) { l++; } if ( MyText[i] == W[l]) { strcat( (*Result) , bits[l]); l = 0; } } } char *BinaryCode; OutputResult1(&BinaryCode); ofstream fout("C:\\Okay.dat", ios::binary); 

What to do next?

  • And who prevents to use fwrite? - Vladimir Martyanov
  • I don’t know how to call this function properly .. fwrite (buffer, 1, sizeof (buffer), ptrFile); where ptrvoid is a pointer to an array of elements to write to the file. size The size in bytes of each element of the array. count The number of elements, each of which occupies size bytes. filestream A pointer to an object of type FILE. I have every element of the array is not 1 byte .. I need to fear that each element of the array (I only have 0 and 1) weighed when writing to the bin. File - bit .. Only then I can compress the file .. - Sasha
  • If you need something to eerily and you ask - try to articulate clearly what needs to be transformed. In the question itself, preferably with examples. - Vladimir Martyanov
  • I have a string of 0 and 1. This line has my message coded. I need to write this string to a binary file. - Sasha
  • one
    In this case, you incorrectly formulate the question. You do not need to transfer the array to a file, but first you need to compress a sequence of zeros and ones so that each zero or one takes up 1 bit. Then all this will go to the file. - Zealint

1 answer 1

I look at your C ++ tag. So we will work with him not on a terrible mixture of C and C ++.

First and foremost, in addition to the data written to the array, you need to know their size, so that you can tell fout.write(...) how much data you want to write. Here, std::vector best for you. Actually, your function takes the form (I will save the transmission of the array to be filled as a parameter, perhaps this is some deep meaning):

 #include <vector> void OutputResult1(std::vector<char> &Result) { Result.clear(); // вообще цикл с занулением можно было заменить одним memset. Result.reserve(1000); // только резервируем память, Result.size() вернёт ноль. size_t l = 0; for ( size_t i = 0; i < MyText.size(); ++i) { // Оставлю на вашей совести проверку выхода за пределы границ в W и bits while (MyText[i] != W[l]) { l++; } if ( MyText[i] == W[l]) { Result.push_back(bits[l]); l = 0; } } } 

Well, the call and recording are made simple:

 // Обратите внимание, указателей тут не используем, используем передачу по ссылке std::vector<char> BinaryCode; OutputResult1(BinaryCode); ofstream fout("C:\\Okay.dat", ios::binary); // для верности проверим if (fout) { // и запишем fout.write(BinaryCode.data(), BinaryCode.size()); } 

The option above simply writes successively from 0 and 1 to the file and you can read it as is. But according to your comments, you want to pack them up to 1 bit. Well ... There are exactly two options here:

  1. Leave the calling code as it is and OutputResult1 remake OutputResult1 that it immediately, during the play, "encodes" the data
  2. Leave the OutputResult1 function as is and change the record to the file.

Consider both options.

Option 1: change OutputResult1

 #include <vector> #include <bitset> // std::bitset void OutputResult1(std::vector<char> &Result) { Result.clear(); // вообще цикл с занулением можно было заменить одним memset. Result.reserve(1000); // только резервируем память, Result.size() вернёт ноль. // пакуем в один байт std::bitset<8> outbits; size_t curbit = 0; size_t l = 0; for ( size_t i = 0; i < MyText.size(); ++i) { // Оставлю на вашей совести проверку выхода за пределы границ в W и bits while (MyText[i] != W[l]) { l++; } if ( MyText[i] == W[l]) { // я не знаю, что хранится в bits, предполагаю '1' и '0' outbits.set(curbit++, bits[l] == '1'); // Как только текущий бит дойдёт до 8 - запишем в Result if (curbit == outbits.size()) { Result.push_back(static_cast<char>(outbits.to_ulong())); curbit = 0; outbits.reset(); } l = 0; } } // тут нужно проверить, что curbit 0, иначе скинуть "недописанный" байт в Result if (curbit) { Result.push_back(static_cast<char>(outbits.to_ulong())); } } 

Option 2: change the calling code

Actually it is done similarly.

 // Обратите внимание, указателей тут не используем, используем передачу по ссылке std::vector<char> BinaryCode; OutputResult1(BinaryCode); ofstream fout("C:\\Okay.dat", ios::binary); // для верности проверим if (fout) { // и запишем... но не сразу. std::vector<char> bitvec; bitvec.reserve(BinaryCode.size() / 8 + 1); // +1 на всякий случай, если у нас некратное 8 число "бит" std::bitset<8> outbits; for (size_t i = 0; i < BinaryCode.size(); ++i) { size_t bit = i % 8; // остаток от деления на 8 всегда будет от 0 до 7 outbits.set(bit, BinaryCode[i] == '1'); if (bit == outbits.size() - 1) { bitvec.push_back(static_cast<char>(outbits.to_ulong())); outbits.reset(); } } // размер некратен 8, значит есть недозаполненый байт, сохраним его if (BinaryCode.size() % 8) { bitvec.push_back(static_cast<char>(outbits.to_ulong())); outbits.reset(); } fout.write(bitvec.data(), bitvec.size()); } 

Conclusion

The code above was written as a demonstration of the idea, from memory and did not test for compilability and performance - I place these procedures on the shoulders of the topic starter.

  • By the way, there is another option with std::vector<bool> , you can explore it yourself and its pitfalls. - Monah Tuk
  • Thank you very much ... Sorry, I now just accidentally opened the bookmark again with my question .. MB is useful to someone and my solution to this problem: - Sasha
  • OutputResult1 (& BinaryCode); for (int i = 0; i <strlen (BinaryCode); i ++) {if (BinaryCode [i] == 48) {x.push_back (0); } else {x.push_back (1); }} ofstream g ("C: \\ Okay.bin"); int amount = 0; char buf = 0; for (int j = 0; j <x.size (); j ++) {buf = buf | x [j] << (7 - amount); amount ++; if (amount == 8) {amount = 0; g << buf; buf = 0; }} g.close (); - Sasha