2016-10-11 11 views
0

標準ライブラリのいくつかの要素のコピーをC言語で作成する必要があり、strcatのコピーを作成する必要があります。だから私はCで2つの文字列を連結する関数を作成する必要があります。私はCの配列は、割り当てられたサイズを変更することはできません知っている。strcatのコピーを作成するには?

char *my_strcat(char *dest, char *src) 
{ 
    int dest_size; 
    int src_size; 
    int current_pos; 
    int free_space; 
    int pos_in_src; 

    src_size = my_strlen(src); 
    dest_size = my_strlen(dest); 
    while (dest[current_pos] != '\0') 
     current_pos = current_pos + 1; 
    free_space = dest_size - current_pos; 
    if (free_space < src_size) 
     return (0); 
    while (src[pos_in_src] != '\0') 
    { 
     dest[current_pos] = src[pos_in_src]; 
     pos_in_src = pos_in_src + 1; 
     current_pos = current_pos + 1; 
    } 
    return (dest); 
} 

しかし、私は私のDESTを宣言する方法を知っているとしていない:私は使用を許可されてるだけfonctionは、私はstrlenを、はstrstrで作られた、と私のコードは次のようになります...)(書き込みコピーでありますメインのsrc。 大きなサイズの配列を作成する方法を知りません。dest = "Hello¥0"のような文字列として宣言しますが、この配列には6文字以上の文字が含まれている必要があります。

お願いします。

+0

なぜポインタと動的メモリ割り当てを使用しないのですか?許可されていませんか? – Cherubim

+2

宛先のサイズは 'strlen(dest)'ではなく、現在の長さにすぎません。 – 4386427

+4

man7.orgから: '文字列は重複していなくてもよく、 dest文字列に結果のための十分なスペースが必要です。 destが で十分でない場合、プログラムの動作は予測不可能です。つまり、メモリ(再)割り当てについて心配する必要はありません。発信者が責任を負います。 – 4386427

答えて

2
char dest[19] = "epite"; 
char *src = "chor42spotted"; 

my_strcat(dest, src); 

また、DESTの文字列が結果に十分なスペースを持っている必要がありますstrcat(3)

ためmanをお読みください。

https://linux.die.net/man/3/strcat

だからあなたの機能が正しく動作している、あなたはあなたが正確にSTDLIBのstrcatのように振る舞う機能mystrcatをしたいdest

1

に十分な空き容量があることをチェックする必要はありません。

だから、プロトタイプは

/* 
    concatenate src to dest 
    dest [in/out] - the string to add to (buffer must be large enough) 
    src [in] - the string to concatenate. 
    Returns: dest (useless little detail for historical reasons). 
*/ 
char *mystrcat(char *dest, const char *src); 

今、私たちはこの

int main(void) 
{ 
char buff[1024]; // nice big buffer */ 

strcpy(buff, "Hello "); 
mystrcat(buff, "world"); 

/* print the output to test it */ 
printf("%s\n", buff); 

return 0; 
} 

のようにそれを呼び出すしかし、私はあなたのためmystrcatを書くつもりはないです。それはあなたの宿題の運動を無意味にするでしょう。

+0

これは私が求めたものではありません(最後の行) – Orionss

+0

プロトタイプは 'char * strcat(char * restrict s1、const char * restrict s2)'です。制限ポインタは、パラメータが同じメモリを指していないと想定できるため、コンパイラがより効果的に動作することを可能にします。 – Lundin

1

配列の1番目のパラメータは、両方の文字列+ 1つのヌル終端文字を含むだけの大きさでなければなりません。たとえば、"hello""world"の場合は、5 + 5 +1 = 11文字が必要です。例:実際のアプリケーションで

#define LARGE_ENOUGH 11 

int main (void) 
{ 
    char str[LARGE_ENOUGH] = "hello"; 
    my_strcat(str, "world"); 
    puts(str); // gives "helloworld" 
} 

は、あなたが一般的になり、同じ多数(数百バイトのカップル)やstrlen関数の呼び出しに基づいて、長さのいずれかに、配列のための領域を割り当てます。


実装自体については、ソリューションは不必要に複雑です。実際のstrcatはすべてのエラーチェックを発信者に任せています。これはおそらく次のように実装されています:

char* strcat (char* restrict s1, const char* restrict s2) 
{ 
    return strcpy(&s1[strlen(s1)], s2); 
} 

ここで最も重要な部分は、s2パラメータのconst正しさに注目することです。

restrictキーワードは、ポインタが異なるメモリ領域を指していると仮定できることをコンパイラに知らせるC標準のマイクロ最適化にすぎません。

ライブラリ関数呼び出しを持たずに自分のバージョンを楽しむだけでロールアウトしたい場合は、まだ簡単ですが、2つのループが必要です。おそらくこのようなもの:

char* lolcat (char* restrict s1, const char* restrict s2) 
{ 
    char* s1_end = s1; 
    while(*s1_end != '\0') // find the end of s1 
    { 
    s1_end++; 
    } 

    do // overwrite the end of s1 including null terminator 
    { 
    *s1_end = *s2; 
    s1_end++; 
    s2++; 
    } while(*s1_end != '\0'); // loop until the null term from s2 is copied 

    return s1; 
} 
関連する問題