我尝试编写一个用户定义的函数,它将完成strcpy()
库函数的功能。但是虽然没有错误,但我的程序崩溃了,而不是将第二个字符串复制到第一个字符串。这段代码有什么问题以及如何修复它?
#include<stdio.h>
#include<string.h>
int main(){
char *ch1="abcd";
char *ch2="efgh";
str_cpy(ch1,ch2);
}
str_cpy(char *c1,char *c2){
int i=0;
while(c1[i]!='\0'){
i++;
}
printf("%c",*(c1+3));
int k;
for(k=0;k<=i;k++){
*(c1+k)=*(c2+k);
}
}
答案 0 :(得分:4)
字符串文字通常被放入只读区域,这就是当你写入c1
时程序崩溃的原因。目标字符串必须是数组或分配的缓冲区:
char c1[5];
str_cpy(c1, c2);
此外,在该函数中,您看起来正在将c2
复制到c1
,但是您计算c1
的长度,您应该计算c2
的长度代替:
// copy string c2 to c1
void str_cpy(char *c1, const char *c2){
int i=0;
while(c2[i]!='\0'){
i++;
}
int k;
for(k=0;k<=i;k++){
*(c1+k)=*(c2+k);
}
}
答案 1 :(得分:3)
您的程序会调用未定义的行为,因为您正在尝试写入字符串文字。字符串文字可以存储在只读存储器中,这可能是您系统中的情况,因此导致崩溃。
请注意,您的字符串复制功能可以在一个循环中执行复制:
char *str_cpy(char *c1, const char *c2) {
for (int i = 0;; i++) {
c1[i] = c2[i];
if (c1[i] == '\0')
return c1;
}
}
您可以使用修改后的main
验证行为:
#include <stdio.h>
char *str_cpy(char *c1, const char *c2) {
for (int i = 0;; i++) {
c1[i] = c2[i];
if (c1[i] == '\0')
return c1;
}
}
int main(void) {
char buf[20];
char *ch2 = "Hello world\n";
printf("%s\n", str_cpy(buf, ch2));
return 0;
}
答案 2 :(得分:0)
以下是您的代码可能的返工,它不必预先定义缓冲区大小(c1)。您只需传递缓冲区地址。另请注意,这样的缓冲区必须在使用后释放(例如,如果在本地范围内声明,而不是在main()
中声明):
#include <stdio.h>
#include <stdlib.h>
char *str_cpy(char **c1, const char *c2) {
int i, size = 0;
for(i = 0; ; i++)
if(c2[i] == '\0')break;
size = i + 1;
if(!(*c1 = realloc(*c1,size*sizeof(char))))
return *c1;//or devise some more sophisticated error handling
for (i = 0;; i++) {
(*c1)[i] = c2[i];
if (c2[i] == '\0')
return *c1;
}
}
int main(void){
char *ch1 = malloc(1); //you're responsible for freeing it, once used
char *ch2 = "Hello, everybody in the neighborhood!";
printf("%s\n",str_cpy(&ch1,ch2));
free(ch1);
return 0;
}
请注意,您不需要#include <string.h>