Quel est le type de vecteur le plus approprié pour conserver les octets d’un fichier?

Quel est le type de vecteur le plus approprié pour conserver les octets d’un fichier?

J’envisage d’utiliser le type int, car les bits “00000000” (1 octet) sont interprétés à 0!

L’objective est de sauvegarder ces données (octets) dans un fichier et de les récupérer ultérieurement.

REMARQUE: les fichiers contiennent des octets nuls (“00000000” en bits)!

Je suis un peu perdu ici. Aidez moi! = D Merci!


MISE À JOUR I:

Pour lire le fichier, j’utilise cette fonction:

char* readFileBytes(const char *name){ std::ifstream fl(name); fl.seekg( 0, std::ios::end ); size_t len = fl.tellg(); char *ret = new char[len]; fl.seekg(0, std::ios::beg); fl.read(ret, len); fl.close(); return ret; } 

NOTE I: Je dois trouver un moyen de m’assurer que les bits “00000000” peuvent être récupérés à partir du fichier!

NOTE II: Des suggestions sur un moyen sûr de sauvegarder ces bits “00000000” dans un fichier?

NOTE III: Lors de l’utilisation du tableau de caractères, j’avais des problèmes pour convertir les bits “00000000” pour ce type.

Extrait de code:

 int bit8Array[] = {0, 0, 0, 0, 0, 0, 0, 0}; char charByte = (bit8Array[7] ) | (bit8Array[6] << 1) | (bit8Array[5] << 2) | (bit8Array[4] << 3) | (bit8Array[3] << 4) | (bit8Array[2] << 5) | (bit8Array[1] << 6) | (bit8Array[0] << 7); 

MISE À JOUR II:

Suivre les recommandations de @chqrlie.

 #include  #include  #include  #include  #include  #include  #include  #include  std::vector readFileBytes(const char* filename) { // Open the file. std::ifstream file(filename, std::ios::binary); // Stop eating new lines in binary mode! file.unsetf(std::ios::skipws); // Get its size std::streampos fileSize; file.seekg(0, std::ios::end); fileSize = file.tellg(); file.seekg(0, std::ios::beg); // Reserve capacity. std::vector unsignedCharVec; unsignedCharVec.reserve(fileSize); // Read the data. unsignedCharVec.insert(unsignedCharVec.begin(), std::istream_iterator(file), std::istream_iterator()); return unsignedCharVec; } int main(){ std::vector unsignedCharVec; // txt file contents "xz" unsignedCharVec=readFileBytes("xz.txt"); // Letters -> UTF8/HEX -> bits! // x -> 78 -> 0111 1000 // z -> 7a -> 0111 1010 for(unsigned char c : unsignedCharVec){ printf("%c\n", c); for(int o=7; o >= 0; o--){ printf("%i", ((c >> o) & 1)); } printf("%s", "\n"); } // Prints... // x // 01111000 // z // 01111010 return 0; } 

MISE À JOUR III:

C’est le code que j’utilise pour écrire dans un fichier binary:

 void writeFileBytes(const char* filename, std::vector& 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); 

MISE À JOUR IV:

Plus d’informations sur UPDATE III :

c ++ – Sauvegarde le contenu d’un “std :: vector ” dans un fichier


CONCLUSION:

La solution au problème des bits “00000000” (1 octet) a été de changer le type qui stocke les octets du fichier en std::vector pour guider les amis. std::vector est un type universel (existe dans tous les environnements) et accepte n’importe quel octal (contrairement à char * dans “UPDATE I”)!

De plus, passer de tableau (caractère) à vecteur (caractère non signé) était crucial pour le succès! Avec vector, je manipule mes données de manière plus sécurisée et totalement indépendante de son contenu (dans char array, j’ai des problèmes avec cela).

Merci beaucoup!

Il y a 3 problèmes dans votre code:

  • Vous utilisez le type char et vous retournez un char * . Cependant, la valeur de retour n’est pas une chaîne C appropriée, car vous n’atsortingbuez pas d’octet supplémentaire pour le terminateur '\0' ni la terminaison null.

  • Si le fichier peut contenir des octets nuls, vous devez probablement utiliser le type unsigned char ou uint8_t pour indiquer explicitement que le tableau ne contient pas de texte.

  • Vous ne renvoyez pas la taille du tableau à l’appelant. L’appelant n’a aucun moyen de dire combien de temps le tableau est. Vous devriez probablement utiliser std::vector ou std::vector au lieu d’un tableau alloué avec new .

Utilisez std::vector . N’utilisez pas std::uint8_t : il n’existera pas sur les systèmes ne disposant pas d’un type de matériel natif de 8 bits exactement. unsigned char existera toujours. il s’agira généralement du plus petit type adressable pris en charge par le matériel. Il doit avoir une largeur minimale de 8 bits. Par conséquent, si vous effectuez un trafic sur 8 octets, il traitera les bits dont vous avez besoin.

Si vous aimez vraiment les types à largeur fixe, vous pouvez envisager std::uint_least8_t , qui existera toujours et comportera au moins huit bits, ou std::uint_fast8_t , qui comportera également au moins huit bits. Cependant, les trafics d’entrées / sorties de fichiers dans les types de caractères, et le mélange de caractères et de variantes avec des types “moins” et “rapide” spécifiés de manière vague peuvent bien devenir confus.

uint8_t est le gagnant à mes yeux:

  • il fait exactement 8 bits ou 1 octet de long;
  • c’est non signé sans que vous deviez taper unsigned chaque fois;
  • c’est exactement la même chose sur toutes les plateformes;
  • c’est un type générique qui n’implique aucune utilisation spécifique, contrairement à char / unsigned char , qui est associé à des caractères de texte, même s’il peut techniquement être utilisé à des fins identiques à celles de uint8_t .

En uint8_t ligne: uint8_t est fonctionnellement équivalent à unsigned char , mais fait mieux de dire qu’il s’agit de données de nature non spécifiée dans le code source.

Utilisez donc std::vector .
#include pour rendre la définition de uint8_t disponible.

PS Comme indiqué dans les commentaires, la norme C ++ définit char comme 1 octet, et l’octet n’est pas, à proprement parler, identique à l’ octet (8 bits). Sur un tel système hypothétique, char existera toujours et durera 1 octet, mais uint8_t est défini comme 8 bits ( octet ) et peut donc ne pas exister (en raison de difficultés de mise en œuvre / de temps système). Donc, char est plus portable, théoriquement, mais uint8_t est plus ssortingct et offre des garanties plus larges quant au comportement attendu.