2

私は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;
}
4

9 に答える 9

8

これは機能します:

#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;
}
于 2013-01-10T14:05:33.173 に答える
3

の最後にコピーする新しいスペースを割り当てる必要がありsます。そうしないと、 while loo[ はアクセスできないメモリに移動します。

malloc() ここについて 学ぶ べきです.

于 2013-01-10T13:59:54.313 に答える
3

文字列リテラルを変更することは未定義の動作でありs、最終的pに は文字列リテラルを指しています。

char* s = "james";

sscat()ローカルchar* pが割り当てられる最初の引数として渡され、次に:

*p=*t;

最初の呼び出しで、文字列リテラルの末尾のヌル文字を上書きしようとしています"james"

malloc()考えられる解決策は、2 つの入力文字列の連結を格納するのに十分な大きさのバッファーを割り当てるために使用することです。

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

それらをそれにコピーします。free()呼び出し元は、返されたを覚えておく必要がありますchar*

ポインターに関するよくある質問のリストが役立つ場合があります。

于 2013-01-10T14:00:32.597 に答える
2

p は文字列の最後まで行ってから、不正なメモリに進み始めるためです。そのため、セグメンテーション違反が発生します。

于 2013-01-10T13:59:07.323 に答える
0

ポインタの基本を理解する必要があります。

char * は文字列や文字の配列ではなく、データの先頭のアドレスです。

char * - char* はできません!!

これは、始めるのに適したチュートリアルです

あなたはmallocを使用する必要があります

于 2013-01-10T14:01:17.970 に答える
0

これは、s が「james\0」を指している、文字列リテラルであり、定数を変更できないためです。

に変更char *s="james";char s[50]="james";ます。

于 2013-01-10T13:58:44.067 に答える
0

ポインタを の末尾に移動し、 のデータを の直後のメモリにs書き込み始めるため、セグメンテーション違反が発生します。の後に書き込み可能なメモリが利用可能であるとあなたが信じる理由は何ですか? 書き込み不可のメモリにデータを書き込もうとすると、セグメンテーション フォールトが発生し、次のメモリは書き込み不可のように見えます (「文字列定数」は通常、読み取り専用メモリに格納されるため、これは予想されることです)。psss

于 2013-01-10T14:09:09.470 に答える
0

いくつかのことが順不同に見えます。

最初に、関数内で作成された何かへのポインターを返したい場合は、どこかで malloc されている必要があることに注意してください。宛先を引数として関数に渡すと、はるかに簡単になります。前者のアプローチに従う場合は、使い終わったら忘れないでくださいfree()

また、関数 scat は、宣言でポインタを返す必要があります。つまりchar *scat、 ではありませんchar scat

最後に、文字列を印刷するためにそのループは必要ありません。文字printf("%s", string);列を印刷する処理を行います (終了している場合)。

于 2013-01-10T14:09:30.130 に答える
0

最初は、以下の行のためにコードが無限ループになります。「p++; t++」ステートメントを含めることで、中括弧を使用することになっていました。

while(*t!='\0')
 *p=*t;

あなたはこのようにしていますが、文字列リテラルの内容を変更しようとしています。これにより、セグメンテーション違反などの未定義の動作が発生します。

二重引用符で囲まれた一連の文字は、文字列リテラルと呼ばれます。「ストリング」とも呼ばれます。文字列のサイズは固定です。一度作成すると、そのサイズを拡張して内容を変更することはできません。これを行うと、未定義の動作が発生します。

この問題を解決するには、渡された 2 つの文字列の長さの合計となるサイズの新しい文字配列を割り当てる必要があります。次に、2 つの文字列を新しい配列に追加します。最後に、新しい配列のアドレスを返します。

#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++;    
    }       
}  
于 2013-01-10T14:36:59.403 に答える