我在两台不同的计算机上使用以下功能。一台计算机正在运行Ubuntu,另一台计算机正在运行OSX。该功能在OS X上有效,但在Ubuntu上不起作用。
#include <stdio.h>
#define MAXBUF 256
char *safe_strncat(char *dest, const char *src, size_t n) {
snprintf(dest, n, "%s%s", dest, src);
return dest;
}
int main(int argc, const char * argv[]){
char st1[MAXBUF+1] = "abc";
char st2[MAXBUF+1] = "def";
char* st3;
printf("%s + %s = ",st1, st2);
st3 = safe_strncat(st1, st2, MAXBUF);
printf("%s\n",st3);
printf("original string = %s\n",st1);
}
在Ubuntu上编译并运行在OS X中的Xcode中编译并运行
最佳答案
您的代码调用了未定义的行为,因为您将目标缓冲区作为snprintf()
格式的源字符串之一传递。不支持:
(强调我的)。
Ubuntu(glibc)和OS/X(Apple libc,基于BSD源)之间snprintf
的实现有所不同。行为是不同的,不能被依赖,因为在所有情况下它都是不确定的。
您可以通过以下方式实现safe_strcat()
:
#include <string.h>
char *safe_strcat(char *dest, size_t size, const char *src) {
char *p = memchr(dest, '\0', size);
if (p != NULL) {
strncat(p, src, size - (p - dest) - 1);
}
return dest;
}
笔记:
safe_strncat()
,它确实是strcat()
的安全版本。 snprintf()
,您仍然不会告诉调用方目标在调用之前是否不是以null终止的(对于safe_strcat
和safe_strncat
)。 您可以对
strcpy
,strncat
和strncpy
的安全版本使用相同的模型(但不能实现strncpy()
的违反直觉的语义):char *safe_strcpy(char *dest, size_t size, const char *src) {
if (size > 0) {
*dest = '\0';
strncat(dest, src, size - 1);
}
return dest;
}
char *safe_strncat(char *dest, size_t size, const char *src, size_t n) {
char *p = memchr(dest, '\0', size);
if (p != NULL) {
if (n > size - (p - dest) - 1)
n = size - (p - dest) - 1;
strncat(p, src, n);
}
return dest;
}
char *safe_strncpy(char *dest, size_t size, const char *src, size_t n) {
if (size > 0) {
if (n > size - 1)
n = size - 1;
*dest = '\0';
strncat(dest, src, n);
}
return dest;
}
关于c - c snprintf用于连接字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40877721/