我在两台不同的计算机上使用以下功能.一台计算机运行Ubuntu,另一台运行OS X.该功能适用于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);
}
Run Code Online (Sandbox Code Playgroud)
编译并在Ubuntu上运行
gcc concat_test.c -o concat_test
./concat_test
abc + def = def
原始字符串= def
在OS X中编译并运行Xcode
abc + def = abcdef
原始字符串= abcdef
您的代码调用未定义的行为,因为您将目标缓冲区作为snprintf()格式的源字符串之一传递.这不受支持:
7.21.6.5
snprintf功能概要
Run Code Online (Sandbox Code Playgroud)#include <stdio.h> int snprintf(char * restrict s, size_t n, const char * restrict format, ...);描述
该
snprintf函数等效于fprintf,除了输出被写入数组(由参数指定s)而不是流.如果n为零,则不写入任何内容,并且s可能是空指针.否则,n-1丢弃st 之外的输出字符而不是写入数组,并在实际写入数组的字符末尾写入空字符.如果在重叠的对象之间进行复制,则行为未定义.
(强调我的).
snprintfUbuntu(glibc)和OS/X(Apple libc,基于BSD源)之间的实现有所不同.行为不同,不能依赖,因为它在所有情况下都是未定义的.
你可以这样实现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;
}
Run Code Online (Sandbox Code Playgroud)
笔记:
safe_strncat(),它确实是一个安全的版本strcat().snprintf(),你仍然不会告诉调用者在调用之前目标是否为空终止(for 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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
471 次 |
| 最近记录: |