我是C的初学者。我想使用指针创建strcat函数。我做到了,但不知道它有什么问题。我使用gcc编译器,它给出了分段错误输出。
#include<stdio.h>
#include<string.h>
char scat(char *,char *);
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
while(*q!='\0') printf("the concatenated string is %c",*q);
}
char *scat(char *s,char *t)
{
char *p=s;
while(*p!='\0'){
p++;
}
while(*t!='\0'){
*p=*t;
p++;
t++;
}
return p-s-t;
}
答案 0 :(得分:5)
这个有效:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *scat(char *,char *); /* 1: your prototype was wrong */
void main()
{
char *s="james";
char *t="bond";
char *q=scat(s,t);
printf("cat: %s\n", q); /* 2: you can use %s to print a string */
free(q);
}
char *scat(char *s,char *t)
{
char *p=malloc(strlen(s)+strlen(t)+1); /* 3: you will have to reserve memory to hold the copy. */
int ptr =0, temp = 0; /* 4 initialise some helpers */
while(s[temp]!='\0'){ /* 5. use the temp to "walk" over string 1 */
p[ptr++] = s[temp++];
}
temp=0;
while(t[temp]!='\0'){ /* and string two */
p[ptr++]=t[temp++];
}
return p;
}
答案 1 :(得分:3)
修改字符串文字是未定义的行为,s
最终p
指向字符串文字:
char* s = "james";
s
作为第一个参数传递给分配了本地scat()
的{{1}},然后:
char* p
在第一次调用时尝试将空字符覆盖在字符串文字*p=*t;
的末尾。
一种可能的解决方案是使用malloc()
来分配足够大的缓冲区以包含两个输入字符串的连接:
"james"
并将其复制到其中。来电者必须记得free()
返回的char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */
。
您可能会发现frequently asked pointer questions列表很有用。
答案 2 :(得分:2)
因为p一直持续到字符串的末尾,然后它开始前进到非法内存。 这就是你得到分段错误的原因。
答案 3 :(得分:2)
您必须在s
的末尾分配要复制的新空间。否则,你的厕所[将进入你无法访问的记忆。
您应该了解malloc()
here。
答案 4 :(得分:0)
这是因为s指向“james \ 0”,字符串文字&amp;你不能修改常数。
将char *s="james";
更改为char s[50]="james";
。
答案 5 :(得分:0)
您需要了解指针的基础知识。
char *不是字符串或字符数组,而是数据开头的地址。
你不能做一个char * - char * !!
This is a good tutorial to start with
您必须使用 malloc
答案 6 :(得分:0)
您遇到分段错误,因为您将指针移动到s
的末尾,然后开始将p
的数据直接写入s
之后的内存中。是什么让你相信在s
之后有可写的内存?任何将数据写入不可写内存的尝试都会导致分段错误,看起来s
之后的内存不可写(这是预期的,因为“字符串常量”通常存储在只读内存中)
答案 7 :(得分:0)
有些事情看起来不合时宜。
首先要记住,当你想要返回指向函数内创建的东西的指针时,它需要在某个地方进行malloc。如果将目标作为参数传递给函数,则会容易得多。如果你遵循前一种方法,那么当你完成它时不要忘记free()
。
此外,函数scat必须返回声明中的指针,即char *scat
,而不是char scat
。
最后你不需要那个循环来打印字符串,printf("%s", string);
将负责为你打印字符串(假设它被终止)。
答案 8 :(得分:0)
首先,由于以下行,您的代码将处于infinte循环中。你应该通过包含“p ++; t ++”语句来使用实心大括号。
while(*t!='\0')
*p=*t;
虽然你喜欢这样,但是你试图改变字符串文字的内容。这将导致未定义的行为,如分段错误。
用双引号括起来的字符序列称为字符串文字。它也被称为“字符串”。字符串的大小是固定的。创建后,您无法扩展其大小并更改内容。这样做会导致未定义的行为。
要解决此问题,您需要分配一个新的字符数组,其大小是传递的两个字符串长度的总和。然后将两个字符串附加到新数组中。最后返回新数组的地址。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char* scat(char *,char *);
void append(char *t , char *s);
int main(void)
{
char *s="james";
char *t="bond";
char *n = scat(s,t);
printf("the concatenated string is %s",n);
return 0;
}
char* scat(char *s,char *t)
{
int len = strlen(s) + strlen(t);
char *tmp = (char *)malloc(sizeof(char)* len);
append(tmp,s);
append(tmp,t);
return tmp;
}
void append(char *t , char *s)
{
//move pointer t to end of the string it points.
while(*t != '\0'){
t++;
}
while( *s != '\0' ){
*t = *s;
t++;
s++;
}
}