如何在C ++中将二进制数据作为向量<complex>获取?

时间:2016-11-04 14:47:10

标签: c++ matlab

我正在尝试读取二进制数据并将它们放在写为:

的文件的向量中
std::ofstream outfile1("channel_1.dat", std::ios::binary | std::ios::out);
//...
outfile1.write((const char*)&buff1.front(), nwrite * sizeof(complex<short>));

我写了代码来读取该文件:

int main(){
    double total_bytes, vector_size;
    streampos begin,end;
    std::ifstream ifs("channel_1.dat", std::ios::binary | std::ios::in);
    begin           = ifs.tellg();
    ifs.seekg (0, ios::end);
    end             = ifs.tellg();
    total_bytes     = end - begin; // 320MB, 32e7 
    vector_size     = total_bytes/ sizeof(complex<short>);  // 8e7
    std::vector<std::complex<float> > v(vector_size);
    ifs.read(reinterpret_cast<char*>(v.data()), vector_size*sizeof(complex<short>));
    ifs.close();

    for(int i=0;i<vector_size; i++){
        std::cout <<i << v[i]<< std::endl;
    }
}

但我仍然得到所有复杂载体的零,大约8e7个样本:

(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
(0,0)
...

我在matlab中使用了相同的文件并且它有效。谁能给我一个帮助?

2 个答案:

答案 0 :(得分:0)

std :: vector buf(N / sizeof(double)); //为N / 8双打保留空间 infile.read(reinterpret_cast(buf.data()),buf.size()* sizeof(double)); //或&amp; buf [0] for C ++ 98

假设整个文件是双倍的,否则这将无法正常工作。 使用这种格式..我希望它会起作用

答案 1 :(得分:0)

short是一个符合平台的签名整数类型。在我的机器上,它长2个字节。 float是一个4字节长的浮点类型。此外,现代机器(包括x86)上的浮点类型与整数类型根本不同,它们也是more complicated。因此,您不能在其二进制表示中取一组2字节整数,并将它们放入float s。如果这样做,您将在浮点变量中获取垃圾,而不是您想要的数据。

因此,正确的变体是声明兼容存储:

std::vector<std::complex<short>> vs(vector_size);

将数据读入其中:

ifs.read(reinterpret_cast<char*>(vs.data()), vector_size*sizeof(complex<short>));

然后将数据复制到浮点数组的向量:

std::vector<std::complex<float> > v(vector_size);
std::copy(vs.begin(), vs.end(), v.begin());
在这种情况下,

std::copy将使用std::complex的赋值运算符,它可以正确处理short - &gt; float基础数据的转换。

最后但并非最不重要。你打电话了

ifs.seekg(0, ios::end);

所以现在你的文件光标位于文件的末尾,任何读取尝试都不会读取任何内容,而vs保持不变。我想你构建了一个调试版本,所以vs最初会保留零。在ifs.read召唤之后你就不会触及它们。要从文件中获取数据,请致电

ifs.seekg(0, ios::beg);
ifs.read之前

。以下是在我的机器上正常工作的整体代码示例:

int main() {
    double total_bytes, vector_size;
    streampos begin,end;
    std::ifstream ifs("data.dat", std::ios::binary | std::ios::in);
    begin           = ifs.tellg();
    ifs.seekg (0, ios::end);
    end             = ifs.tellg();
    total_bytes     = end - begin; // 320MB, 32e7 
    vector_size     = total_bytes/ sizeof(complex<short>);  // 8e7
    std::cout << vector_size << std::endl;
    ifs.seekg(0, ios::beg);
    std::vector<std::complex<short>> vs(vector_size);
    std::vector<std::complex<float> > v(vector_size);
    ifs.read(reinterpret_cast<char*>(vs.data()), vector_size*sizeof(complex<short>));
    std::copy(vs.begin(), vs.end(), v.begin());
    ifs.close();

    for(int i=0;i<vector_size; i++){
        std::cout <<i << v[i]<< std::endl;
    }
    return 0;
}