我有一个16字节的数组,其中包含可执行文件的段名.
char segname[16];
Run Code Online (Sandbox Code Playgroud)
如果段名长度小于16个字节,则其余部分用空字节填充.否则,没有终止空字节.
我想比较segname各种字符串,例如__text.
strncmp使用非空终止字符串调用是否合法?
这篇文章假设它是合法的.此源代码也使其合法化.但是我的男人的页面说:
该
strncmp()函数按字典顺序比较以null结尾的字符串s1和s2.
传递给strncmp的大小将是segname.
我想知道我应该参考什么.
当我解决以下示例算法问题时,我很好奇理解字符串比较在python中如何工作的内部:
给定两个字符串,返回最长公共前缀的长度
我的直觉告诉我,最佳解决方案是在两个单词的开头用一个光标开始并向前迭代,直到前缀不再匹配.就像是
def charByChar(smaller, bigger):
assert len(smaller) <= len(bigger)
for p in range(len(smaller)):
if smaller[p] != bigger[p]:
return p
return len(smaller)
Run Code Online (Sandbox Code Playgroud)
为了简化代码,该函数假定第一个字符串的长度smaller始终小于或等于第二个字符串的长度bigger.
另一种方法是将两个字符串平分以创建两个前缀子字符串.如果前缀相等,我们知道公共前缀点至少与中点一样长.否则,公共前缀点至少不大于中点.然后我们可以递归以找到前缀长度.
阿卡二进制搜索.
def binarySearch(smaller, bigger):
assert len(smaller) <= len(bigger)
lo = 0
hi = len(smaller)
# binary search for prefix
while lo < hi:
# +1 for even lengths
mid = ((hi - lo + 1) // 2) + lo
if smaller[:mid] == bigger[:mid]:
# prefixes equal
lo = mid
else: …Run Code Online (Sandbox Code Playgroud) strncmp如果第三个参数为零,将NULL指针作为参数放入是否安全?即调用如:
strncmp(NULL, "foo", 0);
Run Code Online (Sandbox Code Playgroud) Fortify表示这是一个超出范围的读取:
if (strncmp("test string", "less than 32 char", 32) == 0)
{
...
}
Run Code Online (Sandbox Code Playgroud)
它说该函数从边界外读取数据less than 32 char.
如果strncmp超过32个字符并且第二个字符串少于32个字符,真的有一个发现吗?
从标准中尚不清楚strncmp(来自string.h)
int strncmp(const char *s1, const char *s2, size_t n);
Run Code Online (Sandbox Code Playgroud)
n如果其第三个参数是则应返回0。
根据C17标准草案,7.24.4.4:
该
strncmp函数比较不超过n字符(不比较空字符后面的字符)[...]。
该
strncmp函数返回一个大于、等于或小于零的整数,相应地,因为 指向的 [...] 数组s1大于、等于或小于 指向的 [...] 数组s2。
应该strncmp(s1, s2, 0)返回什么?或者标准对strncmp最后一个论点的情况保持沉默0?
我的直觉告诉我,0作为返回值最有意义:
0是最“对称”的答案(负或正返回值意味着不对称并且与未进行比较不一致)。0与假设的模型一致0,直到发现差异、n进行比较或到达字符串末尾。但上述推理是哲学性的。
似乎该标准在技术上并未声明有关此情况的任何内容。我认为如果这样会更好
0) 或对于它的价值,glibc给我0(没有警告或错误)一堆简单的测试用例,例如strncmp("abc", "def", 0)使用以下编译器标志:
-Wall -Wextra -std=c90 -pedantic
-Wall -Wextra -std=c17 …Run Code Online (Sandbox Code Playgroud) 出于教育目的(是42是),我正在重写strncmp,一个同学走近我,问我为什么要以这种方式转换返回值。我的建议是先打字,然后再取消引用。我的逻辑是我想将char字符串视为未签名的char字符串,然后将其取消引用。
int strncmp(const char *s1, const char *s2, size_t n)
{
if (n == 0)
return (0);
while (*s1 == *s2 && *s1 && n > 1)
{
n--;
s1++;
s2++;
}
return (*(unsigned char *)s1 - *(unsigned char *)s2);
}
Run Code Online (Sandbox Code Playgroud)
他首先要取消引用,然后再进行类型转换,以确保绝对返回两个未签名字符之间的差异。像这样:
return ((unsigned char)*s1 - (unsigned char)*s2);
Run Code Online (Sandbox Code Playgroud)
讨论之后(我同意他的说法,我很奇怪),我们查找了一些可用于生产的实现的源代码,令我们惊讶的是,Apple似乎按照与我相同的顺序进行了铸造/取消引用:
https://opensource.apple.com/source/Libc/Libc-167/gen.subproj/i386.subproj/strncmp.c.auto.html
因此,问题是:在这种情况下有什么区别?为什么选择一个呢?
(我已经找到了以下内容;但是它指定了不同大小的数据类型的强制转换/取消引用,但是对于chars / unsigned chars来说,应该没关系吗?
c/c ++ strncmp签名如下所示:
int strncmp ( const char * str1, const char * str2, size_t num );
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果num为0,返回值是多少?标准怎么说?找不到某些在线文档的答案.
谢谢.
根据我的理解,strcmp()(没有'n'),在任一参数中看到空字符时,立即停止处理并返回结果.
因此,如果其中一个参数已被100%确定地知道为空终止(例如,它是一个字符串文字),那么使用strncmp()(带有'n')调用strlen()作为第三个的一部分没有任何安全性好处将比较限制为已知字符串长度的参数,因为strcmp()它将永远不会读取比已知终止字符串中更多的字符.
事实上,在我看来,调用strncmp()其长度参数是strlen()前两个参数中的一个是唯一的strcmp(),因为它通过评估strlen()表达式来浪费时间线性的已知终止字符串的大小.
考虑:
示例代码A:
if (strcmp(user_input, "status") == 0)
reply_with_status();
Run Code Online (Sandbox Code Playgroud)
示例代码B:
if (strncmp(user_input, "status", strlen("status")+1) == 0)
reply_with_status();
Run Code Online (Sandbox Code Playgroud)
前者对后者有什么好处?因为我在其他人的代码中看到了很多.
我对这些功能的工作原理有缺陷吗?
这是一个foo.c将数据写入共享内存的程序.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
key_t key;
int shmid;
char *mem;
if ((key = ftok("ftok", 0)) == -1) {
perror("ftok");
return 1;
}
if ((shmid = shmget(key, 100, 0600 | IPC_CREAT)) == -1) {
perror("shmget");
return 1;
}
printf("key: 0x%x; shmid: %d\n", key, shmid);
if ((mem = shmat(shmid, NULL, 0)) == (void *) -1) {
perror("shmat");
return 1;
}
sprintf(mem, "hello");
sleep(10);
sprintf(mem, …Run Code Online (Sandbox Code Playgroud) 我在C中编写一个非常简单的函数来检查字符串是绝对路径还是相对路径.无论我尝试什么,它总是返回false.
这是我尝试过的:
int isAbsolute(char *str){
if(strcmp(str,"/")){
return 1;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我称之为:
printf("%d\n", isAbsolute("/"));
Run Code Online (Sandbox Code Playgroud)
每次都返回false.很明显,我错过了一些明显的东西,但我无法弄明白......