我使用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并且直到我得到一个越界错误时才会停止。我很难过,请帮帮忙。
忽略计数,它只是一个帮我调试的变量。
提前致谢。
答案 0 :(得分:2)
为什么不使用memchr()
查找潜在的匹配项?
另外,请确保您正在处理可能已签名类型的促销活动(char
可能会签名,也可能不签名)。请注意,虽然0xff
和0xd9
在设置为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