【问题标题】:How do I read binary data, convert it to an int, then convert it back in C++?如何读取二进制数据,将其转换为 int,然后将其转换回 C++?
【发布时间】:2013-09-07 00:35:02
【问题描述】:

我正在尝试打开一个 wav 文件,读取它,将缓冲区转换为整数数组,然后将其转换回来并写入。

int main(){

    ifstream file ("C:\\Documents\\ParadigmE3-shortened.wav",std::ios_base::out | std::ios_base::binary);

    char * header = new char[50000044];
    file.read(header, 50000044);

    cout << header[0] << endl;

    unsigned int * header_int = new unsigned int[50000044];

    for(unsigned int i = 0; i < sizeof(header); i++){
        header_int[i] = header[i];
    }



    char * writefile = new char[50000044];

    for(unsigned int i = 0; i < sizeof(header); i++){
        itoa(header_int[i], &writefile[i], 10);
    }


    cout << writefile[0] << endl;
    ofstream newfile ("C:\\Documents\\ParadigmE3-modified.wav", std::ios_base::out | std::ios_base::binary);



    newfile.write(writefile, 50000044);

}

目前,这打印:

R
8

表示它在转换过程中改变了数据。我怎样才能让它正常工作?


经过一些建议,学习我可以对char变量进行计算,我重新编写了代码,现在是:

int main(){

    // Create file variable with file
    ifstream file ("C:\\Documents\\ParadigmE3-shortened.wav",std::ios_base::out | std::ios_base::binary);

    // Read the first 15040512 bytes to char array pointer, called header
    char * header = new char[15040512];
    file.read(header, 15040512);

    // Copy contents of header to writefile, after the 44'th byte, multiply the value by 2
    char * writefile = new char[15040512];
    for(int i = 0; i < sizeof(header); i++){
        if(i<44) writefile[i] = header[i];
        if(i>=44) writefile[i] = 2 * header[i];
    }

    // Copy the contents of writefile, but at the 44th byte, divide it by 2, returning it to its original value
    for(int i = 0; i < sizeof(header); i++){
        if(i<44) writefile[i] = writefile[i];
        if(i>=44) writefile[i] = .5 * writefile[i];
    }

    // Create file to write to
    ofstream newfile ("C:\\Documents\\ParadigmE3-modified.wav", std::ios_base::out | std::ios_base::binary);

    // Write writefile to file
    newfile.write(writefile, 15040512);

}

但是,在播放时(在 Windows Media Player 中),它没有播放,所以它显然不是我想要的原始文件。

【问题讨论】:

  • 这有很多问题,我什至不知道从哪里开始。你到底想达到什么目的?
  • 50000044 不能被分成8 的块而没有余数。
  • 不,它读取char 数组缓冲区。而且您不必将其转换为int 数组来对其执行计算,您可以很好地对char 值进行数值运算。在某种程度上,char 只是一个小的int
  • 是的。就像我说的,char 只是一个小的int。 (您确实需要注意 char 可能是“有符号”或“无符号”这一事实 - 即,它可能表示值 -128 到 127,或者它可能表示 0 到 255,具体取决于您使用的特定编译器使用。)
  • (对于某些操作,您需要将数字结果“转换”为char 以将其分配回charchar result = (char) some + mathematical * expression;。这是因为char 是“加宽的” " 到 int 以执行大多数数学运算。)

标签: c++ itoa


【解决方案1】:

我想通了。我学到的几件事是您可以对 8 位 char 变量(最大值为 255 无符号)执行计算,所以我不需要将其更改为 int 数组,但是,我这样做是因为它给了我更多的工作空间(不用担心将值裁剪为 255)。

我已经包含了整个程序(带有标题包含列表),因为我也认为这是一个常见问题,这是迄今为止我见过的最简单的方法(其他方法我做不到弄清楚——做同样的事情要比这复杂得多)。

它读取 wav 文件,然后对数据部分(从第 45 个字节开始)执行操作,然后执行相反的操作,并写入文件,这是原始文件的副本。

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <bitset>
#include <string.h>

using namespace std;

int main(){


    ifstream file ("C:\\Documents\\ParadigmE3-shortened.wav",std::ios_base::out | std::ios_base::binary);

    char * header = new char[15040512];
    file.read(header, 15040512);


    int * writefile = new int[15040512];
    for(int i = 0; i < 15040512; i++){
        if(i<44) writefile[i] = header[i];
        if(i>=44) writefile[i] = 2 * header[i];
    }

    for(int i = 0; i < 15040512; i++){
        if(i<44) header[i] = writefile[i];
        if(i>=44) header[i] = .5 * writefile[i];
    }

    ofstream newfile ("C:\\Documents\\ParadigmE3-modified.wav", std::ios_base::out | std::ios_base::binary);


    newfile.write(header, 15040512);

}

【讨论】:

  • 你想用这个做什么?让它更响亮?那样真的不行。
  • 对我来说效果很好(在示例中我颠倒了它,所以它是原始的,但只是减半会降低音量)。
  • 嗯...还是有很多问题!基础知识:将 C 和 C++ 头文件混合在一起、内存泄漏等。等待发生的细微错误:在处理整数时,乘以 0.5 不是乘以 2 的逆运算。我可以继续。这只是糟糕
  • @NikBougalis 听起来很糟糕。我猜 0.5 是一个浮点数,所以它必须将浮点数转换为整数,但并非总是如此?
  • 它也不关注每个样本的位数或8位数据无符号但16位有符号的事实。
猜你喜欢
  • 1970-01-01
  • 2011-07-24
  • 2021-07-14
  • 1970-01-01
  • 1970-01-01
  • 2014-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多