strlen没有返回正确的长度

时间:2015-04-08 14:22:58

标签: c strlen

我目前正在使用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时总是停止,我认为这会让它与'\0'混淆!所以我想知道是否有替代这种方法,或者你有什么建议可以解决这个问题。

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

5 个答案:

答案 0 :(得分:4)

unsigned char Response[269]={0x00};

这会将Response初始化为269个相同值的序列,每个值都为零。请注意,0x000'\0'都是一样的。

strlen(Response)

这实际上是无效的,尽管有些编译器可能允许它。 strlen需要char*类型的参数; Response是一个unsigned char数组,转换为unsigned char*类型的指针。类型不兼容,并且没有隐式转换。您应该收到编译时警告(如果有,请在您的问题中包含警告)。

如果我们将Response的定义更改为:

char Response[269] = {0x00};

然后strlen调用变为有效 - 并将返回0strlen会扫描第一个'\0'空字符 - 并且您已使用空字符填充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一次并使用存储的值。

然而,您可能不希望首先使用strlenstrlen适用于字符串。 “字符串”是由空字符(0'\0'0x00)终止的字符序列。您似乎有一系列无符号字符,其中0x00是有效值,而不是终结符。您需要通过其他方式跟踪长度,而不是使用strlen来计算数组的长度。

答案 1 :(得分:3)

00'\0'是一回事。

看起来您可以使用数组来查找数组的长度而不是字符串的长度。 strlen会将数组扫描到第一个空终止符。对于任意数组没有等价物,所以你需要自己跟踪它。

答案 2 :(得分:2)

到目前为止,我看到的其他答案正在围绕这个真正的问题跳舞。你需要了解你正在处理什么样的字符串

按照历史惯例,C将字符串表示为 null终止字符数组。这是strlen期望的那种字符串。但是你的“字符串”包含空字节。所以它不是一个以空字符结尾的字符串,而strlen将不会做你想要的。

更重要的是,strlen 极其危险,绝不应在现代代码中使用。使用strlen很容易导致安全漏洞,如果您的程序使用strlen来检查通过网络收到的响应,则可能会利用您的程序实现拒绝或服务甚至远程执行代码。< / p>

更安全的替代方案是strnlen如果,则为其提供正确的大小限制。关于正确的解决方案很难更准确,因为在你的例子中,正确的答案总是269,所以实际上没有可变长度的字符串可以测量。

答案 3 :(得分:0)

你的意思是数组的长度而不是响应的长度,所以你想要sizeof(Response)而不是strlen(Response) - 大概你知道响应是269个字节长,因为那是什么卡协议定义。

您还需要Response_PPSE为2 * 269 + 1个字节长,否则您的printf语句将在数组末尾运行。并且您需要设置Response_PPSE [2 * 269] = 0以使其成为有效的以null结尾的字符串。

答案 4 :(得分:0)

在我创建的应用程序中,我使用以下方法创建了一个自定义“strlen”方法,以便正确计算长度,即使我的数据中间有空字节:

- 我们需要使用除了包含数据的char *,以及malloc的大小。 - 我将以下参数传递给方法:第一个参数是char * str,第二个是malloc的大小。

-Method以相反的方式工作,从MAX内存地址(str +第二个参数的内存地址)到第一个内存大小,while循环递减最大内存地址,直到达到第一个内存地址,但是这个while循环将中断,以防万一第一个非NULL / 0字符到达。

- 最后我们返回最后MAX存储器地址和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;
}