strlen return 长度不正确
strlen does not return the right length
我目前正在使用 strlen
方法来计算此字符串的长度:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
主要的问题是遇到00
总是停止,我觉得是和'[=15=]'
搞混了!所以我想知道是否有此方法的替代方法,或者您是否可以提出任何建议来解决此问题。
P.S: 我不确定这个问题是否重复我搜索了同样的问题但没有找到满意的答案!
已编辑:
我的代码:
unsigned char Response[269]={0x00};
unsigned char Response_PPSE[269];
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
strlen 只计算这个字节的长度:
56 69 56 4F 74 65 63 68 32 00
00
和'[=11=]'
是一回事。
看起来您可以通过数据数组来获取数组的长度而不是字符串的长度。 strlen
将扫描数组直到第一个空终止符。任意数组没有等效项,因此您需要自己跟踪它。
unsigned char Response[269]={0x00};
这会将 Response
初始化为 269 个相同值的序列,每个值均为零。请注意 0x00
、0
和 '[=17=]'
都是一回事。
strlen(Response)
这实际上是无效的,尽管某些编译器可能允许这样做。 strlen
需要一个 char*
类型的参数; Response
是unsigned char
的数组,转换为unsigned char*
类型的指针。类型不兼容,并且没有隐式转换。您应该收到编译时警告(如果收到,请在您的问题中包含警告)。
如果我们把Response
的定义改成:
char Response[269] = {0x00};
然后 strlen
调用生效 -- 并将 return 0
。 strlen
扫描第一个 '[=17=]'
空字符 -- 您已经用空字符填充了 Response
。
在你的问题的顶部,你说你有一个字符串:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
这与您向我们展示的代码没有任何关系。这也是模棱两可的;它是一串十六进制数字和空格:"56 69 56 ..."
,还是类似于 "\x56\x69\x56..."
?如果 56 69
序列旨在表示数组的内容,请更新您的问题以显示创建它的实际代码。
最后:
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
在循环的每次迭代中调用 strlen
可能效率很低。 strlen
每次都必须扫描整个字符串以确定其长度。一旦你解决了其他问题,你应该在循环之前调用一次 strlen
并使用存储的值。
但是,您可能一开始就不想使用 strlen
。 strlen
应用于 字符串 。 "string" 是由空字符终止的字符序列(0
、'[=17=]'
、0x00
)。您似乎有一系列 unsigned 字符,其中 0x00
是有效值,而不是终止符。不是使用 strlen
来计算数组的长度,而是需要通过其他方式跟踪长度。
到目前为止我看到的其他答案都是围绕这里的真正问题跳舞。这就是您需要了解您正在处理的字符串类型。
根据历史惯例,C 将字符串表示为 空终止 字符数组。这是 strlen
期望的那种字符串。但是您的 "string" 包含空字节。所以它不是一个以 null 结尾的字符串,strlen
不会做你想做的事。
更重要的是,strlen
极度危险,绝不能在现代代码中使用。使用 strlen 很容易导致安全漏洞,如果您的程序使用 strlen
检查通过网络收到的响应,您的程序很可能会被利用来实现拒绝或服务甚至远程代码执行。
一个更安全的选择是strnlen
,如果你给了它正确的大小限制。正确的解决方案很难更精确,因为在您的示例中,正确答案始终是 269,因此实际上没有要测量的可变长度字符串。
你指的是数组的长度而不是响应的长度,所以你想要 sizeof(Response) 而不是 strlen(Response) - 大概你知道响应是 269 字节长,因为这是卡协议定义。
您还需要 Response_PPSE 为 2*269+1 字节长,否则您的 printf 语句将 运行 超出数组的末尾。并且您需要设置 Response_PPSE[2*269]=0 以使其成为有效的空终止字符串。
在我制作的应用程序中,我使用以下方法创建了自定义 "strlen" 方法,以便正确计算长度,即使我的数据中间有空字节也是如此:
-除了包含数据的 char * 之外,我们还需要使用 malloc 的大小。
-我将以下参数传递给该方法:第一个参数是 char * str,第二个是 malloc 的大小。
- 方法以相反的方式工作,从 MAX 内存地址(str 的内存地址 + 第二个参数)到第一个内存大小,while 循环递减最大内存地址直到达到第一个内存地址但是这个 while 循环将中断以防万一到达第一个非 NULL/0 字符。
- 最后我们return char * 的最后一个最大内存地址和第一个内存地址的差值,+1。
这是我的代码:
size_t utils_strlen(const char * str, int max) {
const char * maxs;
maxs = str + max;
while(str<maxs) {
if(*maxs!=0) break;
maxs--;
}
return(maxs-str)+1;
}
我目前正在使用 strlen
方法来计算此字符串的长度:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
主要的问题是遇到00
总是停止,我觉得是和'[=15=]'
搞混了!所以我想知道是否有此方法的替代方法,或者您是否可以提出任何建议来解决此问题。
P.S: 我不确定这个问题是否重复我搜索了同样的问题但没有找到满意的答案!
已编辑:
我的代码:
unsigned char Response[269]={0x00};
unsigned char Response_PPSE[269];
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
strlen 只计算这个字节的长度: 56 69 56 4F 74 65 63 68 32 00
00
和'[=11=]'
是一回事。
看起来您可以通过数据数组来获取数组的长度而不是字符串的长度。 strlen
将扫描数组直到第一个空终止符。任意数组没有等效项,因此您需要自己跟踪它。
unsigned char Response[269]={0x00};
这会将 Response
初始化为 269 个相同值的序列,每个值均为零。请注意 0x00
、0
和 '[=17=]'
都是一回事。
strlen(Response)
这实际上是无效的,尽管某些编译器可能允许这样做。 strlen
需要一个 char*
类型的参数; Response
是unsigned char
的数组,转换为unsigned char*
类型的指针。类型不兼容,并且没有隐式转换。您应该收到编译时警告(如果收到,请在您的问题中包含警告)。
如果我们把Response
的定义改成:
char Response[269] = {0x00};
然后 strlen
调用生效 -- 并将 return 0
。 strlen
扫描第一个 '[=17=]'
空字符 -- 您已经用空字符填充了 Response
。
在你的问题的顶部,你说你有一个字符串:
56 69 56 4F 74 65 63 68 32 00 2C 00 00 27 6F 23 84 0E 32 50 41 59 2E 53 59 53 2E 44 44 46 30 31 A5 11 BF 0C 0E 61 0C 4F 07 A0 00 00 00 04 10 10 87 01 01
这与您向我们展示的代码没有任何关系。这也是模棱两可的;它是一串十六进制数字和空格:"56 69 56 ..."
,还是类似于 "\x56\x69\x56..."
?如果 56 69
序列旨在表示数组的内容,请更新您的问题以显示创建它的实际代码。
最后:
for(i=0;i<=strlen(Response);i++)
sprintf(Response_PPSE+(2*i),"%02X",Response[i]);
在循环的每次迭代中调用 strlen
可能效率很低。 strlen
每次都必须扫描整个字符串以确定其长度。一旦你解决了其他问题,你应该在循环之前调用一次 strlen
并使用存储的值。
但是,您可能一开始就不想使用 strlen
。 strlen
应用于 字符串 。 "string" 是由空字符终止的字符序列(0
、'[=17=]'
、0x00
)。您似乎有一系列 unsigned 字符,其中 0x00
是有效值,而不是终止符。不是使用 strlen
来计算数组的长度,而是需要通过其他方式跟踪长度。
到目前为止我看到的其他答案都是围绕这里的真正问题跳舞。这就是您需要了解您正在处理的字符串类型。
根据历史惯例,C 将字符串表示为 空终止 字符数组。这是 strlen
期望的那种字符串。但是您的 "string" 包含空字节。所以它不是一个以 null 结尾的字符串,strlen
不会做你想做的事。
更重要的是,strlen
极度危险,绝不能在现代代码中使用。使用 strlen 很容易导致安全漏洞,如果您的程序使用 strlen
检查通过网络收到的响应,您的程序很可能会被利用来实现拒绝或服务甚至远程代码执行。
一个更安全的选择是strnlen
,如果你给了它正确的大小限制。正确的解决方案很难更精确,因为在您的示例中,正确答案始终是 269,因此实际上没有要测量的可变长度字符串。
你指的是数组的长度而不是响应的长度,所以你想要 sizeof(Response) 而不是 strlen(Response) - 大概你知道响应是 269 字节长,因为这是卡协议定义。
您还需要 Response_PPSE 为 2*269+1 字节长,否则您的 printf 语句将 运行 超出数组的末尾。并且您需要设置 Response_PPSE[2*269]=0 以使其成为有效的空终止字符串。
在我制作的应用程序中,我使用以下方法创建了自定义 "strlen" 方法,以便正确计算长度,即使我的数据中间有空字节也是如此:
-除了包含数据的 char * 之外,我们还需要使用 malloc 的大小。
-我将以下参数传递给该方法:第一个参数是 char * str,第二个是 malloc 的大小。
- 方法以相反的方式工作,从 MAX 内存地址(str 的内存地址 + 第二个参数)到第一个内存大小,while 循环递减最大内存地址直到达到第一个内存地址但是这个 while 循环将中断以防万一到达第一个非 NULL/0 字符。
- 最后我们return char * 的最后一个最大内存地址和第一个内存地址的差值,+1。
这是我的代码:
size_t utils_strlen(const char * str, int max) {
const char * maxs;
maxs = str + max;
while(str<maxs) {
if(*maxs!=0) break;
maxs--;
}
return(maxs-str)+1;
}