2013-01-10 46 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++;  
    }  
}