根据我的理解,strcmp()
(没有'n'),当在任一参数中看到空字符时,立即停止处理并返回结果。
因此,如果已知其中一个参数100%确定为空终止(例如,它是一个字符串文字),那么使用strncmp()
(带'n')调用时没有任何安全优势。 strlen()
作为将比较限制为已知字符串长度的第三个参数的一部分,因为strcmp()
将永远不会读取比已知终止字符串中更多的字符。
事实上,在我看来,对前两个参数之一的长度参数为strncmp()
的{{1}}的调用仅与strlen()
的情况不同。通过评估strcmp()
表达式,浪费了已知终止字符串大小的线性时间。
考虑:
示例代码A:
strlen()
示例代码B:
if (strcmp(user_input, "status") == 0)
reply_with_status();
前者对后者有什么好处?因为我在其他人的代码中看到了很多。
我对这些功能的运作方式存在缺陷吗?
答案 0 :(得分:5)
在您的特定示例中,我会说使用strncmp
是不利的,因为:
strlen
进行扫描"status"
所有这些都会增加混乱,如果它确实短于6个字符且包含与测试字符串相同的字符,那么在任何情况下都不会溢出user_input
。
那将是例外。如果您知道输入字符串的内存总是超过测试字符串中的字符数,那么请不要担心。否则,可能需要担心,或者至少要考虑它。 strncmp
对于测试大缓冲区内的内容非常有用。
我更喜欢代码可读性。
答案 1 :(得分:4)
是的。如果在strncmp中使用strlen,它将遍历指针,直到它在字符串中看到null。这使它在功能上等同于strcmp。
答案 2 :(得分:4)
在你给出的特定情况下,它确实没用。然而,稍微改变是更常见的:
if (strncmp(user_input, "status", strlen("status")) == 0)
reply_with_status();
此版本仅检查user_input
是否以"status"
启动,因此它具有不同的语义。
答案 3 :(得分:2)
除了检查字符串的开头是否与输入匹配的技巧之外,strncmp仅在您不能100%确定字符串在其分配空间结束之前终止时才会有用。
因此,如果你有一个固定大小的缓冲区,你可以使用:
strncmp(user_input, "status", sizeof(user_input))
因此,确保您的比较不会溢出。
但是在这种情况下你必须要小心,因为如果你的user_input没有以null结尾,那么它将真正检查user_input是否与状态的开始匹配。
更好的方法可能是:
if (user_input[sizeof(user_input) - 1] != '\0') {
// handle it, since it is _not_ equal to your string
// unless filling the buffer is valid
}
else if (strcmp(user_input, "status")) { ... }
答案 4 :(得分:0)
现在,我同意这对使用strncmp()并不是特别有用,而且我在strcmp()中看不到任何好处。
但是,如果我们在+1
之后移除strlen
来更改代码,那么它就会开始变得有用。
strncmp(user_input, "status", strlen("status"))
因为它将user_input
的前6个字符与“状态”进行比较 - 这至少有时是有意义的。
所以,如果+1
存在,它就变成了常规的strcmp
- 这只是浪费时间来计算长度。但是没有+1
,这是一个非常有用的比较(在适当的情况下)。
答案 5 :(得分:0)
strncmp()使用有限。如果在两个字符串中的任何一个上遇到NUL,则正常的strcmp()将停止。 (在这种情况下,字符串是不同的)Strncmp()将停止并返回零(“字符串在前N个字符中相等”)
stncmp()的一个可能用途是解析选项,直到非重要部分,例如
if (!strncmp("-st", argv[xx], 3)) {}
,对于“-string”或“-state”或“-st0”返回零,但不为“-sadistic”。