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

How to get binary data as a vector<complex> in C++?

本文关键字:lt 向量 complex gt C++ 获取 数据 二进制      更新时间:2023-10-16

我正试图读取二进制数据,并将它们从文件中写入矢量:

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;
    }
}

但是对于所有的复向量,我仍然得到0,大约8e7个样本:

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

我在matlab中使用了相同的文件,它工作了。有人能帮帮我吗?

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

假设整个文件是double,否则这将无法正常工作。使用这种格式…我希望它能成功

short是一个有符号平台相关的整数类型。在我的机器上,它是2字节长。float是一个4字节长的浮点类型。此外,现代机器(包括x86)上的浮点类型与整数类型有本质上的不同,它们也更复杂。所以你不能把一组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 -> 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;
}