我在MacOS 11.6.1上,希望将一个字符附加到一个字符串中,并从其中复制以下内容:https://www.geeksforgeeks.org/how-to-append-a-character-to-a-string-in-c/
我应该有以下几点:
Original String: Geek
Character to be appended: s
Appended String: Geeks
但只有以下一条(最后一行遗漏了)
Original String: Geek
Character to be appended: s
我做错了什么?
这是代码
// C program to Append a Character to a String
#include <stdio.h>
#include <string.h>
int main()
{
// declare and initialize string
char str[6] = "Geek";
// declare and initialize char
char ch = 's';
// print string
printf("Original String: %s\n", str);
printf("Character to be appended: %c\n", ch);
// append ch to str
strncat(str, &ch, 1);
// print string
printf("Appended String: %s\n", str);
return 0;
}
发布于 2022-11-05 13:27:34
这是strncat
中的一个bug,特别是用于实现它的__builtin___strn_chk
例程。请考虑以下问题中的代码摘要:
char str[6] = "Geek";
char ch = 's';
strncat(str, &ch, 1);
正如所发生的那样,编译器将ch
放在内存中的str
前面。检查编译的程序集输出显示,strncat
是通过调用__builtin___strn_chk
实现的。在调试器中逐步遍历__builtin___strn_chk
会显示它调用__chk_overlap
来检查源缓冲区和目标缓冲区是否重叠。对于此调用,它将传递长度为6的str
地址(其中的四个字符加上要连接的新字符以及其后的终止空字符)和长度为2的ch
地址。
此长度为2是不正确的;strncat
或__builtin___strn_chk
只应从ch
中提取一个字符。这在__builtin___strn_chk
中是一个错误;它应该传递长度为1,而不是2。__chk_overlap
正确地确定它被传递的缓冲区重叠并生成一个陷阱。
这可以可靠地通过以下方式复制:
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[] = "xabc\0\0";
strncat(buffer+1, buffer, 1);
}
使用__builtin___strncat_chk
是因为<string.h>
包含一个标头secure/_string.h
,它将strncat
定义为宏:
#define strncat(dest, ...) \
__builtin___strncat_chk (dest, __VA_ARGS__, __darwin_obsz (dest))
因此,我们可以通过将strncat
替换为(strncat)
来解决错误,这将强制使用strncat
函数而不是宏。还可以在包含#undef strncat
之后使用<string.h>
。
发布于 2022-11-05 12:17:49
好的,下面是一些程序员的评论和Eric的评论,我可以使用strcpy()代替strncat来解决这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char str[6] = "Geek";
char ch = 's';
size_t lenstr = strlen(str);
char *str2 = malloc(lenstr + 1 + 1);
strcpy(str2, str);
str2[lenstr] = ch;
str2[lenstr + 1] = '\0';
printf("Original String: %s\n", str);
printf("Character to be appended: %c\n", ch);
printf("Appended String: %s\n", str2);
return 0;
}
https://stackoverflow.com/questions/74327153
复制相似问题