使用C++转换二进制字符数组而不会丢失前导 0



我正在尝试将mp3转换为二进制fstream(或十六进制,两者都可以使用(。我已经想好了如何打开文件并将内容输出到控制台。但是在二进制和十六进制中,前面的0都被删除了。因此,如果我从fstream创建一个新的mp3,它将丢失许多位。如有任何关于保留原始格式的帮助,我们将不胜感激。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
ifstream myfile; // Declare variable to hold the location of file
myfile.open("src/ShortTest.mp3", std::ios::binary); //open short file with sample data
if (!myfile.is_open())
{
cout << "Cannot read file!" << endl;
}
else
{
cout << "File is open!" << endl;
while ( getline (myfile,line) ) {
int n = line.length();
int remainder = 0;
for (int i = 0; i <= n; i++) {
// convert each char to
// ASCII value
int val = int(line[i]);
// Convert ASCII value to binary
string bin = "";
while (val > 0) {
(val % 2)? bin = '1'+bin : bin = '0'+bin ;
val /= 2;
}
cout << bin << " ";
remainder = (i+1) % 8;
if ( remainder == 0) {
cout << endl;
}
}
}
myfile.close();
}
cout << "Done!" << endl;
return 0;
}

输出:

File is open!
1001001 1000100 110011 11    1 
1001 1100010 1010100 1001001 1010100 110010   
1100    1010011 1110100 1110101 
1110000 1101001 1100100 100000 1010011 1101111 1101110 1100111 
1010100 1000011 1001111 1001110    111 
1001111 1110100 1101000 1100101 1110010 
1010100 1001011 1000101 1011001    
10    1000101 1010100 1011000 1011000 
Done!

我的预期输出是我在十六进制编辑器中看到的

File is open!
01001001 01000100 00110011 00000011 00000000 00000000 00000000 00000001 
00001001 01100010 01010100 01001001 01010100 00110010 00000000 00000000  
00000000 00001100 00000000 00000000 00000000 01010011 01110100 01110101 
01110000 01101001 01100100 00100000 01010011 01101111 01101110 01100111 
01010100 01000011 01001111 01001110 00000000 00000000 00000000 00000111  
00000000 00000000 00000000 01001111 01110100 01101000 01100101 01110010  
00000000 01010100 01001011 01000101 01011001 00000000 00000000 00000000
00000010 00000000 00000000 00000000 01000101 01010100 01011000 01011000  
Done!

可能最简单的方法是使用std::bitset进行转换。

哦,最好避免使用using namespace std;std::endl。假设您正在读取您认为是二进制文件的内容,那么std::getline也没有多大意义。哦,错误消息通常应该写入标准错误流,而不是标准输出流。

#include <iostream>
#include <fstream>
#include <string>
#include <bitset>
int main(int argc, char **argv) {
if (argc < 2) {
std::cerr << "Usage: bindump <filename>n";
return EXIT_FAILURE;
}
std::ifstream myfile(argv[1], std::ios::binary);
if (!myfile.is_open())
{
std::cerr << "Cannot read file!n";
}
else
{
unsigned i =0;
char ch;
while (myfile.get(ch)) {
std::cout << std::bitset<8>(ch) << " ";
++i;
if (i == 8) {
i = 0;
std::cout << "n";
}
}
std::cout << "n";
}
}

当您将val转换为bin时,您将把val的任何数字转换为二进制字符串。如果你想让这个字符串是8位,前面有0,那么在你创建bin之后,在你输出之前,只需要添加一个while循环

while(bin.length()<8){bin="0"+bin;}

这样的东西行吗?

#include <algorithm>
#include <bitset>
#include <fstream>
#include <iostream>
#include <iterator>
void show_binary(unsigned char c) {
static auto count = 0u;
std::cout << std::bitset<8>(c) << " ";
if ((++count % 8u) == 0u) {
std::cout << "n";
count = 0u;
}
}
void dump(const char* path) {
std::ifstream fp(path, std::ios::in | std::ios::binary);
std::for_each(std::istreambuf_iterator<char>(fp),
std::istreambuf_iterator<char>(), show_binary);
}
int main(int argc, char* argv[]) {
std::for_each(argv + 1, argv + argc, dump);
}

最新更新