配列を手動で1回ループし、各文字配列のstrlenのカウントを取得して合計し、合計値を使用して宛先を割り当ててから、配列を再度ループする必要がありますか?
文字の配列を含む配列のサイズをどのように見つけて、それらを反復処理できるようにしますか?
文字の配列を含む配列のサイズをどのように見つけて、それらを反復処理できるようにしますか?
2つの方法があります:
char*
を割り当て、NUL文字を使用して文字列を終了するのと同じように、ヌルポインタをセンチネルとして格納します。つまり、Cは目的の情報を提供しないため、配列を割り当てるときに独自の簿記を行う必要があります。2番目の提案に従うと、文字列の配列内の文字の総数を次のように取得できます。
size_t sum_of_lengths(char const **a)
{
size_t i, total;
for (i = total = 0; a[i] != NULL; i++)
total += strlen(a[i]);
return total;
}
'\0'
実際の連結を行うときは、スペースを予約することを忘れないでください。
配列内のすべての文字列を連結した文字列を作成しようとしていると思います。
これを行うには2つの方法があります。
提案どおりに2つのパスを作成し、最初のパスで長さを合計し、宛先の文字列を割り当ててから、2番目のパスで文字列を追加します
1パスします。バッファをあるサイズに割り当てることから始めます。合計サイズを追跡しながら、文字列を追加します。文字列用の十分なスペースがない場合は、。を使用してバッファを再割り当てしrealloc()
ます。再割り当ての最も効率的な方法は、毎回バッファのサイズを2倍にすることです。
文字列を連結したいと思います。もしそうなら、はい。割り当てる前に、必要なスペースの量を知っておく必要があります。
実際、を使用することはできますがrealloc
、実際には毎回前の文字列をコピーするだけであり、効果ははるかに低くなります。
いくつかのコード:(仮定しchar *s[]
てint n
)
int i,l=1;
for (i=0;i<n;i++) l+=strlen(s[i]);
char *r=malloc(l);
r[0]=0;
for (i=0;i<n;i++) strcat(r,s[i]);
編集:いくつかのコメントとしてstrcat
、あなたが長さを知っているときは効果がありません。(一度にメモリを割り当てるので、私はまだそれを好みます。)いくつかのより効果的なコードは次のとおりです。
int i,l=1;
for (i=0;i<n;i++) l+=strlen(s[i]);
char *r=malloc(l);
char *d=r;
for (i=0;i<n;i++) {
srtcpy(d,s[i]);
d+=strlen(s[i]);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *nstrdup(char **args);
int main (int argc, char **argv)
{
char * this;
this = nstrdup(argv+1);
printf("[%s]\n", this );
return 0;
}
char *nstrdup(char **args)
{
size_t len, pos;
char **pp, *result;
len = 0;
for (pp = args; *pp; pp++) {
len += strlen (*pp);
}
result = malloc (1+len);
pos = 0;
for (pp = args; *pp; pp++) {
len = strlen (*pp);
memcpy(result+pos, *pp, len);
pos += len;
}
result[pos] = 0;
return result;
}