如何在C中覆盖字符串的一部分?
例如,我有一个字符串。我只想更改字符串开头的几个字符,其余的保持原样。在C中实现这一点的最佳方法是什么如何在C中覆盖字符串的一部分?,c,c-strings,C,C Strings,例如,我有一个字符串。我只想更改字符串开头的几个字符,其余的保持原样。在C中实现这一点的最佳方法是什么 #include <stdio.h> #include <string.h> int main() { char src[40]; char src2[40]; char dest[12]; memset(dest, '\0', sizeof(dest)); strcpy(src, "This is a string");
#include <stdio.h>
#include <string.h>
int main() {
char src[40];
char src2[40];
char dest[12];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is a string");
strcpy(src2, "That");
strncpy(dest, src, sizeof(src));
strncpy(dest, src2, sizeof(src2));
printf("Final copied string : %s\n", dest);
}
#包括
#包括
int main(){
char-src[40];
char-src2[40];
char dest[12];
memset(dest,'\0',sizeof(dest));
strcpy(src,“这是一个字符串”);
strcpy(src2,“该”);
strncpy(目的地、src、规模(src));
strncpy(dest,src2,sizeof(src2));
printf(“最终复制的字符串:%s\n”,dest);
}
我希望将字符串从“这是一个字符串”
更改为“这是一个字符串”
有没有一种简单的方法可以完成我所缺少的任务?sizeof(src2)
是40
(它是整个数组的大小)-您可能指的是strlen(src2)
(这只是用于字符串的字符数):
请注意,您的代码存在缓冲区溢出问题:dest
数组不够大,无法容纳生成的字符串。它至少需要17个字符才能容纳“这是一个字符串”
字符串。您还需要使用:
strncpy(dest, src, strlen(src));
这里有几个问题 首先,
dest
的长度只有12个字节,太短,无法容纳“这是一个字符串”。尝试将该字符串复制到dest
将溢出缓冲区。这引起了人们的注意。使它至少有20个字节
第二个sizeof(src)
给出整个数组的大小,即40,而不是字符串的长度。如果目标缓冲区不够大,这也将给出未定义的行为。改用strlen。这同样适用于sizeof(src2)
通过这些更改,您应该具有以下功能:
#include <stdio.h>
#include <string.h>
int main() {
char src[40];
char src2[40];
char dest[20];
memset(dest, '\0', sizeof(dest));
strcpy(src, "This is a string");
strcpy(src2, "That");
strncpy(dest, src, strlen(src));
strncpy(dest, src2, strlen(src2));
printf("Final copied string : %s\n", dest);
}
#包括
#包括
int main(){
char-src[40];
char-src2[40];
char dest[20];
memset(dest,'\0',sizeof(dest));
strcpy(src,“这是一个字符串”);
strcpy(src2,“该”);
strncpy(目的地、src、strlen(src));
strncpy(dest,src2,strlen(src2));
printf(“最终复制的字符串:%s\n”,dest);
}
我对memset()
调用感到困惑和有点担心。memset
调用允许使用strncpy(),而不必担心终止'\0'。此类调用假定此逻辑将用于从更高级别函数调用的通用函数中
如果不是这样,则应将第一个strncpy()替换为strcpy,并放弃memset:
#包括
#包括
int main(){
char-src[40];
char-src2[40];
char dest[20];
/*memset(dest,'\0',sizeof(dest));--不需要这个*/
strcpy(src,“这是一个字符串”);
strcpy(src2,“该”);
strcpy(dest,src,strlen(src));/*strcpy将在末尾放一个'\0'*/
strncpy(dest,src2,strlen(src2));
printf(“最终复制的字符串:%s\n”,dest);
}
但是,如果这将从更高级别的函数调用,那么我们确实需要检查传入字符串的长度和/或malloc dest缓冲区并释放它。memset()是房间里的大象,它表明还有更多的逻辑需要考虑。否则,只需将第一个strncpy()替换为strcpy()。通过@dbush扩展答案: 我认为代码仍然很脆弱
#include <stdio.h>
#include <string.h>
int main() {
char src[40];
char src2[40];
char dest[20];
但是,用0初始化其他数组也是一个好主意
memset(src, '\0', sizeof(src));
memset(src2, '\0', sizeof(src2));
旁注:当然,只要使用数组初始化语法,就可以省去memset的麻烦:
char src[40] = {0};
char src2[40] = {0};
char dest[20] = {0};
接下来的两行是潜在的危险,前提是这两个字符串可能不是字符串常量。(即使如此!)也不提供长度检查。。。更好:
// strcpy(src, "This is a string");
// strcpy(src2, "That");
strncpy(src, "This is a string", sizeof(src)- 1);
strncpy(src2, "That", sizeof(src2) -1);
这样我们可以确保不会造成任何溢出。
我们还确保src和src2中的字符串正确地以null结尾
现在,将src/src2复制到dest也是危险的。我们必须确保不会溢出dest
//strncpy(dest, src, strlen(src));
//strncpy(dest, src2, strlen(src2));
更好:
strncpy(dest, src, sizeof(dest) - 1);
strncpy(dest, "That is a long rubbish string that easily could overflow dest", sizeof(dest) -1);
我们只复制尽可能多的dest可以保存和保留空终止符
现在开始替换前X个字符。同样,我们必须确保没有溢出发生。我们使用strlen来确定src2中以null结尾的字符串的实际大小,但需要使用/计算dest的最大大小。因此,斯特伦和西泽夫的混合物
memcpy只是为了好玩。你也可以使用strncpy
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
memcpy(dest,src2,strlen(src2)
}
因此,整个安全实现如下所示:
#include <stdio.h>
#include <string.h>
int main() {
char src[40] = {0};
char src2[40] = {0};
char dest[20] = {0};
strncpy(src, "This is a string", sizeof(src)- 1);
strncpy(src2, "That is a long rubbish string and sooooooooooooooooooooooooo much more", sizeof(src2) -1);
strncpy(dest, src, sizeof(dest) - 1);
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
}
#包括
#包括
int main(){
char src[40]={0};
char src2[40]={0};
char dest[20]={0};
strncpy(src,“这是一个字符串”,sizeof(src)-1);
strncpy(src2),“这是一个很长的垃圾字符串,所以更多”,sizeof(src2)-1;
strncpy(目的地、src、规模(目的地)-1);
memcpy(dest,src2,strlen(src2)
请注意,sizeof的使用似乎仅等同于strlen;在有效的字符类型上,在其他类型上,您需要做更多的工作。您需要研究字符串在C中的工作方式以及它们是如何终止的。您还需要了解字符串的长度和字符串所在数组的大小之间的差异。这是错误的
strncpy(dest,src,sizeof(src))代码>使用源代码的大小作为限制是无用的。目的地的大小才是最重要的dest
最多只能保存11个字符的字符串,而src
最多可以保存39个字符的字符串。由于src
保存的字符串长度超过11个字符,因此会导致缓冲区溢出,从而导致未定义的行为。@Gerhardh这并不是毫无用处,因为OP需要字符串长度。实现这一点并再次保护的一种方法
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
#include <stdio.h>
#include <string.h>
int main() {
char src[40] = {0};
char src2[40] = {0};
char dest[20] = {0};
strncpy(src, "This is a string", sizeof(src)- 1);
strncpy(src2, "That is a long rubbish string and sooooooooooooooooooooooooo much more", sizeof(src2) -1);
strncpy(dest, src, sizeof(dest) - 1);
memcpy(dest, src2, strlen(src2) < sizeof(dest) ? strlen(src2) : sizeof(dest));
printf("Final copied string : %s\n", dest);
}