![](/img/trans.png)
[英]How to write a unsigned char* array containing hex values to file in python
[英]Searching for 2 consecutive hex values in a char array of a file
我已经使用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时,它都会失败。 当我不将十六进制值转换为无符号字符时,程序不会进入while循环,当我这样做时,程序会遍历数组中的所有字符,并且直到出现超出范围的错误才会停止。 我很困惑,请帮忙。
忽略计数,它只是一个可以帮助我调试的变量。
提前致谢。
为什么不使用memchr()
查找潜在的匹配项?
另外,请确保您要处理的潜在签名类型的促销活动( char
可能签名也可能未签名)。 请注意,虽然将0xff
和0xd9
视为8位值时已将其高位设置,但它们是非负整数常量,因此不会发生“符号扩展”:
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;
}
使用void * memmem(const void * haystack,size_t haystacklen,const void * needle,size_tneedlelen);
在string.h中可用,并且易于使用。
char* searchBuffer(char* b, int len)
{
unsigned char needle[2] = {0xFF, 0XD9};
char * c;
c = memmem(b, len, needle, sizeof(needle));
return c;
}
您正在整数促销中犯规。 !=
(和类似的)的两个操作数都提升为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
,并避免进行所有强制转换。
[请注意,最重要的是,您的循环逻辑是不正确的,正如各种注释所指出的。]
4E将提升自己为正整数,但是*p1
对于FF将为负,然后将提升为非常大的无符号值,该值将远大于FF。
您需要使p1
无符号。
您可以将代码编写得更短:
char* searchBuffer(const char* b) {
while (*b != '\xff' || *(b+1) != '\xd9') b++;
return b;
}
还要注意,如果b实际上不包含字节FFD9,则该函数将导致分段错误(或更糟糕的是,返回无效结果)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.