En gros, la principale différence entre un fichier binaire et un fichier texte est que chaque octet que vous écrivez dans le premier est enregistré sans modification, tandis qu'un caractère de nouvelle ligne écrit dans le second peut être traduit en séquence de nouvelle ligne du système sous-jacent, par exemple retour chariot + saut de ligne pour Windows.
Voici un exemple :
#include <fstream>
#include <ios>
int main() {
std::ofstream file;
std::string s = "Hello, World!\n";
// file.open("binary", std::ios_base::binary);
file.open("text");
file.write(s.c_str(),s.size());
file.close();
}
Si je compile ce programme tel qu'il est maintenant avec g++ et que je l'exécute sous Windows, j'obtiens ce résultat :
$ od -c text
0000000 H e l l o , W o r l d ! \r \n
0000017
Si je commente la ligne où le fichier "texte" est écrit et décommente celle où le fichier "binaire" est écrit, j'obtiens :
$ od -c binary
0000000 H e l l o , W o r l d ! \n
0000016
( od
est une commande d'UNIX/Linux qui affiche le contenu exact d'un fichier)
Pour répondre à votre question, voici un exemple de la façon dont vous pourriez le faire "à la main". En utilisant un bitset
comme dans la réponse acceptée, est probablement une approche plus raisonnable :
#include <fstream>
#include <ios>
#include <iostream>
#include <string>
#include <vector>
int main() {
std::string s = "10100101111111110000";
std::vector<unsigned char> v;
unsigned char c = 0;
int i = 0;
for ( auto d : s ) {
if ( d == '1' )
++c;
c <<= 1;
++i;
if ( i % 8 == 0 ) {
v.push_back(c);
c = 0;
i = 0;
}
}
if ( i != 0 ) {
c <<= 8 - i;
v.push_back(c);
}
std::basic_ofstream<unsigned char> file;
file.open("binary", std::ios_base::binary);
file.write(v.data(), v.size());
file.close();
}