抱歉,标题太长了。我不知道如何用简短的词来形容。
您是否愿意重现我遇到的问题?
您可以使用任何wav文件进行读取。
我正在尝试在wav文件中查询块,这是代码的简化版本,但是我认为如果有问题,可能足以重新创建。
我使用的是Mac,并使用g++ -std=c++11
进行编译。
当我运行此代码并且不包括行std::cout << query << std::endl;
时,std::find(chunk_types.begin(), chunk_types.end(), query) != chunk_types.end()
在所有迭代中均返回0。但是我知道二进制文件包含其中一些块。如果我加入这行,那么它可以正常工作,但是那也是不可预测的,可以说有时候它可以正常工作。
我有点困惑,我在这里做错什么了吗?
#include <fstream>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
int main(){
std::vector<std::string> chunk_types{
"RIFF","WAVE","JUNK","fmt ","data","bext",
"cue ","LIST","minf","elm1",
"slnt","fact","plst","labl","note",
"adtl","ltxt","file"};
std::streampos fileSize;
std::ifstream file(/* file path here */, std::ios::binary);
file.seekg(0, std::ios::beg);
char fileData[4];
for(int i{0};i<100;i+=4){ //100 is an arbitrary number
file.seekg(i);
file.read((char*) &fileData[0], 4);
std::string query(fileData);
std::cout << query << std::endl;
/* if i put this std::cout here, it works or else std::find always returns 0 */
if( std::find(chunk_types.begin(), chunk_types.end(), query) != chunk_types.end() ){
std::cout << "found " + query << std::endl;
}
}
return 0;
}
答案 0 :(得分:4)
std::string query(fileData)
在strlen
上使用fileData
来查找其终止0,但未找到一个,因为fileData
并不以0结尾,并继续在0上搜索0。堆栈,直到找到它或在堆栈末尾击中不可访问的内存并导致SIGSEGV
。
此外,file.read
读取的符号少于预期的符号,必须使用gcount
提取上次读取的实际字符数:
修正:
file.read(fileData, sizeof fileData);
auto len = file.gcount();
std::string query(fileData, len);
一种更有效的解决方案是直接读入std::string
并继续重用它以避免内存分配(如果没有短字符串优化)和复制:
std::string query;
// ...
constexpr int LENGTH = 4;
query.resize(LENGTH);
file.read(&query[0], LENGTH);
query.resize(file.gcount());