C++ 在无符号字符数组中搜索字符
我正试图读取一个二进制数据文件。文件中的值是8位无符号整数,例如,记录分隔符是ASCII文本$MSG,$GRP。我将数据视为一大块,如下所示:C++ 在无符号字符数组中搜索字符,c++,arrays,string,C++,Arrays,String,我正试图读取一个二进制数据文件。文件中的值是8位无符号整数,例如,记录分隔符是ASCII文本$MSG,$GRP。我将数据视为一大块,如下所示: unsigned char *inBuff = (unsigned char*)malloc(file_size*sizeof(unsigned char)); result = fread(inBuff, sizeof(unsigned char), file_size, pFile); 我需要搜索这个数组来找到以$GRP开头的记录,这样我就可以
unsigned char *inBuff = (unsigned char*)malloc(file_size*sizeof(unsigned char));
result = fread(inBuff, sizeof(unsigned char), file_size, pFile);
我需要搜索这个数组来找到以$GRP开头的记录,这样我就可以读取下面的数据,有人能推荐一个好方法吗?我试过几种方法,但没有一种有效。例如,我最近的尝试是:
std::stringstream str1;
str1 << inBuff;
std::string strTxt = str1.str();
然而,当我检查这个长度时,它只有5。我看了一下记事本中的文件,注意到第六个字符是空的。所以它似乎是因为空而被切断的。有什么想法吗?假设fread不返回-1,其中的值将告诉您有多少字节可供搜索
期望能够对二进制数据执行字符串搜索是不合理的,因为二进制数据中可能有NUL字符,这将导致长度函数提前终止
搜索数据的一种可能方法是在缓冲区中使用搜索键和搜索键的长度。根据我的评论
C str函数假定以零结尾的字符串。任何C字符串函数都将在第一个二进制0处停止。使用memchr定位$,然后使用strncmp或memcmp。特别是,不要假设紧跟在4字节标识符之后的字节是二进制0
在代码C中,未测试:
不要混合C和C++。使用fstream并直接将文件读入std::字符串。如果你仍然想要/需要坚持你的C代码,不要混合C和C++。对于i=0,则使用;你能提供一些示例代码和示例文件吗?听起来很容易通过strstr和sscanf实现。@Dogbert鉴于该文件包含8位无符号整数,其中一些是0或NULL,我非常确定strstr不是一个可行的解决方案,我怀疑std::string是否也能工作。根据问题描述,OP是一个二进制文件,而不是简单的文本文件。@user3386109它实际上是一个二进制文件,包含二进制和ASCII值。不过,划界并不难,如果我们将is视为ASCII,我们就可以找到边界。
/* recordId should point to a simple string such as "$GRP" */
unsigned char *find_record (unsigned char *data, size_t max_length, char *recordId)
{
unsigned char *ptr;
size_t remaining_length;
ptr = startOfData;
if (strlen(recordId) > max_length)
return NULL;
remaining_length = max_length;
do
{
/* fast scan for the first character only */
ptr = memchr (ptr, recordId[0], remaining_length);
if (!ptr)
return NULL;
/* first character matches, test entire string */
if (!memcmp (ptr, recordId, strlen(recordId))
return ptr;
/* no match; test onwards from the next possible position */
ptr++;
/* take care not to overrun end of data */
/* It's tempting to test
remaining_length = ptr - startOfData;
but there is a chance this will end up negative, and
size_t does not like to be negative.
*/
if (ptr >= startOfData+max_length)
break;
remaining_length = ptr-startOfData;
} while (1);
return NULL;
}