C ++ bitshift导致另一个变量的问题

时间:2018-03-29 16:28:23

标签: c++ bit-manipulation bitwise-operators bit-shift

我正在学习c ++,并决定作为第一个制作wave文件解析器的项目。我有想要获取ChunkSize的逻辑,但由于某种原因,wav.ChunkSize的位移会导致wav.ChunkID在末尾附加2个额外的字符。

#include <fstream>
#include <iterator>
#include <vector>
#include <iostream>
#include <bitset>
#include "bwave.h"
#include  <cstdint>
using  namespace std;

bwave wav;

int main(){
    std::ifstream input("cello.wav", std::ios::binary);

    std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(input)),(std::istreambuf_iterator<char>()));

    for (int i = 0; i < 60 ; ++i)
    {
        std::cout << "Byte " << i << ": ";
        std::cout  << buffer[i] <<" ";
        std::cout << "\n";
    }

    wav.ChunkID[0] = buffer[0];
    wav.ChunkID[1] = buffer[1];
    wav.ChunkID[2] = buffer[2];
    wav.ChunkID[3] = buffer[3];

    wav.Type[0] = buffer[8];
    wav.Type[1] = buffer[9];
    wav.Type[2] = buffer[10];
    wav.Type[3] = buffer[11];

    wav.DataStart[0] = buffer[36];
    wav.DataStart[1] = buffer[37];
    wav.DataStart[2] = buffer[38];
    wav.DataStart[3] = buffer[39];

    unsigned char tmp[4];

    // ChunkSize    
    for (int i = 4; i < 8 ; ++i)
    {
        switch(i){
        case 4:
            tmp[3] = buffer[i];
            std::cout << bitset<8>(tmp[3]) << "\n";
            break;
        case 5: 
            tmp[2] = buffer[i];
            std::cout << bitset<8>(tmp[2]) << "\n";
            break;
        case 6: 
            tmp[1] = buffer[i];
            std::cout << bitset<8>(tmp[1]) << "\n";
            break;
        case 7: 
            tmp[0] = buffer[i];
            std::cout << bitset<8>(tmp[0]) << "\n";
            break;
        default:
            printf("%s\n","Error!" );
            break;
        } 
    }

    std::cout << bitset<24>(tmp[0] << 24  | tmp[1] << 16 | tmp[2] << 8 | tmp[3] ) << "\n";

    wav.ChunkSize = tmp[0] << 24  | tmp[1] << 16 | tmp[2] << 8 | tmp[3];

    // Datasize
    for (int i = 40; i < 44 ; ++i)
    {
        switch(i){
        case 40:
            tmp[3] = buffer[i];
            break;
        case 41: 
            tmp[2] = buffer[i];
            break;
        case 42: 
            tmp[1] = buffer[i];
            break;
        case 43: 
            tmp[0] = buffer[i];
            break;
        default:
            printf("%s\n","Error!" );
            break;
        } 
    }
    //wav.DataSize = tmp[0] << 24  | tmp[1] << 16 | tmp[2] << 8 | tmp[3];

    std::cout << "Header: "    <<   wav.ChunkID << "\n";
    std::cout << "Size: "      <<   wav.ChunkSize << "\n";
    std::cout << "Type: "      <<   wav.Type << "\n";
    std::cout << "Data: "      <<   wav.DataStart << "\n";
    std::cout << "Data Size: " <<   wav.DataSize << "\n";

    return 0;
}

输出以下内容。

...
Byte 59:  
00101010
01100011
00001100
00000000
000011000110001100101010
Header: RIFF*c
Size: 811818
Type: WAVE
Data: data
Data Size: 

此外,我对任何最佳做法的建议持开放态度。

参考 - http://soundfile.sapp.org/doc/WaveFormat/

感谢您的时间, 乙

编辑 - bwave文件

struct bwave{
    char ChunkID[4];
    uint ChunkSize;
    char Type[4];
    char Format[4];
    uint NumChannels;
    uint SampleRate;
    uint BPS;
    char DataStart[4];
    char DataSize;
};

1 个答案:

答案 0 :(得分:0)

看起来我的问题已经解决了!我通过给我的char数组1个额外的字节来修复它。我认为这是有效的,因为C期望一个空终止符,如果它没有看到一个内存做了一些东西赢了。喜欢打印我不想要的角色。 最后的修复如下。

char ChunkID[4]; -> char ChunkID[5];

谢谢大家的帮助!