Tho*_*son 11 c c-standard-library
似乎strncmp通常建议比strcmp,有什么优势?我认为这可能与安全有关.如果是这种情况,如果已知其中一个输入字符串是字面常量,它仍然适用"LiteralString"吗?
更新:
我的意思是在需要比较整个字符串的相同用户场景下,strncmp可以如下使用.我想知道它是否有意义.
strncmp(inputString, "LiternalString", strlen("LiternalString"));
Run Code Online (Sandbox Code Playgroud)
Sur*_*ati 19
问题strcmp在于,有时,如果错误地,传递的参数不是有效的C字符串(意味着p1或p2不以空字符终止,即不以NULL结尾的字符串),那么,strcmp继续比较直到它到达不可访问的内存和崩溃或有时导致意外的行为.
使用strncmp您可以限制搜索,以便它不会到达不可访问的内存.
但是,从那以后不应该说这strcmp是不安全的.这两种功能都非常适合它们的工作方式.程序员man在使用之前应该读取该函数的页面,并且在将参数传递给这样的库函数时必须足够真诚.
您还可以阅读包含几乎相似问题的THIS.
R..*_*R.. 12
strncmp没有"优势strcmp"; 而是他们解决不同的问题.strcmp用于确定两个字符串是否相等(如果不相同,可能如何相对于彼此对它们进行排序/排序).strncmp(主要)用于确定字符串是否以特定前缀开头.例如:
if (strncmp(str, "--option=", 9)==0)
Run Code Online (Sandbox Code Playgroud)
将确定是否str以"--option=".开头.如果不strcmp修改要检查的字符串(可能不是有效的操作)或制作无用的副本,就无法实现这一点.memcmp除非你已经知道str一个对象的长度至少为9个字节,否则它也无法实现; 否则调用memcmp会有未定义的行为.
还有其他用例strncmp,例如使用非C字符串数据.
...在需要比较整个字符串的相同用户场景下,...
strncmp(inputString, "LiternalString", strlen("LiternalString"));
Run Code Online (Sandbox Code Playgroud)
inputString考虑字符串比字符串文字长的情况。
const char *inputString = "LiternalString_XYZ";
int cmp = strncmp(inputString, "LiternalString", strlen("LiternalString"));
printf("%d\n", cmp); // prints 0.
Run Code Online (Sandbox Code Playgroud)
但OP想要比较整个字符串。
const char *inputString = "LiternalString_XYZ";
int cmp = strcmp(inputString, "LiternalString");
printf("%d\n", cmp); // prints non-zero.
Run Code Online (Sandbox Code Playgroud)
OP直接问题的结论
我想知道这是否有意义。
不。要比较整个字符串,strncmp()无法始终提供正确的结果。使用strcmp()。
更远
strncmp(s1,s2,n)可以限制搜索,以便在正确计算的情况下 n它不会到达不可访问的内存- 这在OP的代码中没有完成,并且当和 的最佳n值不同时,正确执行会出现问题。s1s2
大小限制n适用于两者s1,s2因此使该函数可用于比较前缀,但不“更安全”。
在OP的情况下,由于字符串文字的字符串长度,没有理由因为“安全”而限制搜索,因为字符串文字 始终包含终止空字符。
如果有的话,n应该是基于 的某些属性inputString。
类似的代码strncmp(s1, string_literal, strlen(s1))在功能上不正确,因为比较错过了空字符。稍微好一点的是strncmp(s1, string_literal, strlen(s1)+1),但这在功能上与更简单的相同,strcmp(s1, string_literal)并且“安全性”没有降低。
下面提供了一些改进的“安全性”,以防foo()没有正确形成 字符串N != M,但如果如上所述,可能会提供错误的答案。
char s1[N];
foo(s1); // populate s1 somehow
int cmp = strncmp(s1, string_literal, sizeof s1);
char s1[N];
char s2[M];
foo(s1); // populate s1 somehow
foo(s2); // populate s2 somehow
int cmp = strncmp(s1, s2, min(sizeof s1, sizeof s2));
Run Code Online (Sandbox Code Playgroud)
但在这些情况下,问题出在foo(),而不是这里。
对我来说,如果foo()有如此疑问,我会使用以下内容
s1[sizeof s1 - 1] = '\0';
s2[sizeof s2 - 1] = '\0';
int cmp = strcmp(s1, s2);
Run Code Online (Sandbox Code Playgroud)
或检测foo()未形成字符串。
char s1[N];
foo(s1);
if (memchr(s1, '\0', sizeof s1) == NULL) Oops();
Run Code Online (Sandbox Code Playgroud)
这个故事的寓意是:strncmp()不是“更安全”的版本strcmp()。它是一个用于不同工作的工具:比较字符串前缀。
| 归档时间: |
|
| 查看次数: |
18482 次 |
| 最近记录: |