2013-01-10 45 views
2

我是C的初学者。我想使用指针创建strcat函数。我做到了,但不知道它有什么问题。我使用gcc编译器,它给出了分段故障输出。C编程strcat使用指针

#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; 
} 
+1

顺便说一句,主函数应该返回一个int而不是void。请确保您的编译器配置为发出警告。 – hugomg

回答

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; 
} 
+0

通过指出评论中的错误,你的解释方式令人惊叹。谢谢哥们 !!!!!! –

0

这是因为s指向“詹姆斯\ 0”字符串文字&你不能修改常量。

char *s="james";更改为char s[50]="james";

2

因为p一直走到字符串的末尾,然后它开始前进到非法的内存。 这就是为什么你得到分段错误。

+0

你是什么意思推进到非法?指针p递增到字符串结尾,所以p-s-t是由我完成的,以达到字符串的第一个地址,然后使用间接运算符*来获取字符。提前感谢。 (char * s,char * t) –

+0

char * scat(char * s,char * t) char * p = s; while(* p!='\ 0'){//这里表示你已经到达“string”的末尾了 p ++; //你正在前进指针 } while(* t!='\ 0'){ * p = * t; p ++; //在这里你正在前进字符串的结尾。 t ++; } return p-s-t; } – hmatar

2

您必须分配新空间才能在s的末尾进行复制。否则,你的厕所[将进入你无法访问的内存。

您将了解到malloc()here

3

这是不确定的行为来修改字符串文字和s,并最终p,指向一个字符串:

char* s = "james"; 

s其中地方char* p被指定为第一个参数传递给scat()和然后:

*p=*t; 

其上第一调用试图overwite空字符的字符串文字"james"的末尾。

一种可能的解决办法是使用malloc()分配足够大的缓冲器来包含两个输入字符串的concatentation:

char* result = malloc(strlen(s) + strlen(p) + 1); /* + 1 for null terminator. */ 

,并将它们复制到其中。来电者必须记得free()返回char*

您可能会找到有用的列表frequently asked pointer questions

0

您需要了解指针的基础知识。

char *不是字符串或字符数组,它是数据开始的地址。

你不能做char * - char * !!

This is a good tutorial to start with

,你将不得不使用的malloc

+0

但正如你在第二行中所说的那样,它指向数据开始的地址,所以地址必须是整数。那么,为什么我不能从int –

+0

中获得一个int值,它会给你一个新的地址,但它是无用的。 –

0

你得到一个分段错误,因为你将指针移动到的s结束,然后就开始将p的数据写入s之后的存储器中。什么让你相信在s之后有可用的可用内存?任何将数据写入不可写内存的尝试都会导致分段错误,看起来像s之后的内存不可写(这是因为“字符串常量”通常存储在只读存储器中)。

0

几件事看起来不顺从。

首先要记住,当你想返回一个指向函数内创建的东西的指针时,它需要在某处被malloc化。如果您将目的地作为参数传递给函数,则会更容易。如果你遵循前一种方法,当你完成它时不要忘记free()

而且,函数scat必须在声明中返回一个指针,即char *scat而不是char scat

最后,您不需要该循环来打印字符串,printf("%s", string);将负责为您打印字符串(只要它已终止)。

0

起初,由于下面的行,您的代码将处于无限循环。你应该通过包含“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++;  
    }  
}