在文件的char数组中搜索2个连续的十六进制值

时间:2011-05-22 18:10:59

标签: c arrays search pointers hex

我使用fread将文件读入一个字符数组。现在我想在该数组中搜索两个连续的十六进制值,即FF后跟D9(它是表示文件末尾的jpeg标记)。这是我用来做的代码:

char* searchBuffer(char* b) {
    char* p1 = b;
    char* p2 = ++b;
    int count = 0;

    while (*p1 != (unsigned char)0xFF && *p2 != (unsigned char)0xD9) {
        p1++;
        p2++;
        count++;
    }

    count = count;
    return p1;
}

现在我知道如果我搜索不包含0xFF的十六进制值(例如4E后跟46),此代码有效,但每次尝试搜索0xFF时都会失败。当我没有将十六进制值转换为unsigned char时,程序不会进入while循环,当我执行程序遍历数组中的所有chars并且直到我得到一个越界错误时才会停止。我很难过,请帮帮忙。

忽略计数,它只是一个帮我调试的变量。

提前致谢。

5 个答案:

答案 0 :(得分:2)

为什么不使用memchr()查找潜在的匹配项?

另外,请确保您正在处理可能已签名类型的促销活动(char可能会签名,也可能不签名)。请注意,虽然0xff0xd9在设置为8位值时具有高位设置,但它们是非负整数常量,因此不会出现“符号扩展”:< / p>

char* searchBuffer(char* b) {
    unsigned char* p1 = (unsigned char*) b;
    int count = 0;

    for (;;) {
        /* find the next 0xff char */
        /* note - this highlights that we really should know the size   */
        /* of the buffer we're searching, in case we don't find a match */
        /* at the moment we're making it up to be some large number     */
        p1 = memchr(p1, 0xff, UINT_MAX);
        if (p1 && (*(p1 + 1) == 0xd9)) {
            /* found the 0xff 0xd9 sequence */
            break;
        }

        p1 += 1;
    }

    return (char *) p1;
}

另外,请注意,如果找不到目标,你应该传递一些被搜索缓冲区大小的概念。

这是一个采用缓冲区大小参数的版本:

char* searchBuffer(char* b, size_t siz) {
    unsigned char* p1 = (unsigned char*) b;
    unsigned char* end = p1 + siz;

    for (;;) {
        /* find the next 0xff char */
        p1 = memchr(p1, 0xff, end - p1);
        if (!p1) {
            /* sequnce not found, return NULL */
            break;
        }


        if (((p1 + 1) != end) && (*(p1 + 1) == 0xd9)) {
            /* found the 0xff 0xd9 sequence */
            break;
        }

        p1 += 1;
    }

    return (char *) p1;
}

答案 1 :(得分:1)

您正在违反整数促销!=(和类似)的两个操作数都被提升为int。如果其中至少有一个是unsigned,那么它们都被视为unsigned(实际上这不是100%准确,但对于这种特殊情况,它应该就足够了)。所以这个:

*p1 != (unsigned char)0xFF

相当于:

(unsigned int)*p1 != (unsigned int)(unsigned char)0xFF

在您的平台上,char显然是signed,在这种情况下,它永远不会占用(unsigned int)0xFF的值。

请尝试按如下方式投射*p1

(unsigned char)*p1 != 0xFF

或者,你可以让函数取unsigned char个参数而不是char,并避免所有的转换。

[请注意,除此之外,您的循环逻辑不正确,正如各种评论中所指出的那样。]

答案 2 :(得分:1)

4E会将自身提升为正整数,但*p1将对FF为负,然后将提升为非常大的无符号值,远远大于FF。

您需要p1 无符号。

答案 3 :(得分:1)

您可以将代码写得更短:

char* searchBuffer(const char* b) {
    while (*b != '\xff' || *(b+1) != '\xd9') b++;
    return b;
}

另请注意,如果b实际上不包含字节FFD9,则该函数将导致分段错误(或更糟糕的是,返回无效结果)。

答案 4 :(得分:1)

使用void * memmem(const void * haystack,size_t haystacklen,const void * needle,size_t needlelen);

在string.h中可用且易于使用。

echo "Going inside Server-Node";
cd ./../Server-Node
echo "Starting Node Server";
npm start & echo OK
echo 'Going inside ionic-Project';
cd ./../learn-ionic
echo 'Starting ionic server';
ionic serve