在无符号字符数组中搜索字符

searching an unsigned char array for characters

本文关键字:字符 搜索 数组 无符号      更新时间:2023-10-16

我有一个二进制数据文件,我试图读取。文件中的值是8位无符号整数,以ASCII文本(例如$MSG, $GRP)作为"record"分隔符。我将数据作为一个大块读取,如下所示:

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。我在记事本中查看了该文件,并注意到第六个字符是NULL。因此,由于NULL,它似乎在那里被切断了。什么好主意吗?

假设读取不返回-1,其中的值将告诉您有多少字节可供搜索。

期望能够对二进制数据进行字符串搜索是不合理的,因为二进制数据中可能存在NUL字符,这将导致length函数提前终止。

搜索数据的一种可能的方法是在缓冲区上使用memcmp,使用搜索键和搜索键的长度。

(根据我的评论)

c str函数假设字符串以零结尾。任何C字符串函数都会在第一个二进制0处停止。使用memchr来定位$,然后使用strncmpmemcmp。特别是,不要假设紧跟在4字节标识符后面的字节是二进制0

在代码中(C, 未测试):

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