C言語で無限長文字列(ちょー簡易版)
C言語で無限長文字列を扱う関数を書いてみました。
普通、C言語でこういうことをやろうとすると、文字列用の構造体を作って、そこに今の文字列の長さと格納可能な長さ(確保済みバッファの長さ)を覚えておきます(たしかglibとかRubyのstring.cはそうなっていたと思います)。で、確保済みバッファが足りなくなったら、バッファのサイズを2倍とか1.5倍とかに拡張します(reallocの回数を減らすために、このようにしていたと思います)。
が、今回は面倒なので構造体を作らずに素のchar *を扱うことにします。なので、reallocは毎回発生します。効率が必要な用途には使わない方がよいでしょう。あー、C++だったらこんなこと考えなくてもいいのに。みたいな。
#include <stdlib.h> #include <string.h> #include <assert.h> char * str_init(char *s) { assert(s != NULL); return strdup(s); } char * str_append(char *dst, char *src) { size_t dstlen; size_t srclen; assert(dst != NULL); assert(src != NULL); dstlen = strlen(dst); srclen = strlen(src); dst = realloc(dst, dstlen + srclen + 1); if (dst == NULL) { free(dst); return NULL; } strncat(dst, src, srclen); return dst; } #include <stdio.h> int main(int argc, char *argv[]) { char *s = str_init("foo"); printf("<%s>\n", s); /* => <foo> */ s = str_append(s, "bar"); if (s == NULL) goto err; printf("<%s>\n", s); /* => <foobar> */ s = str_append(s, "baz"); if (s == NULL) goto err; printf("<%s>\n", s); /* => <foobarbaz> */ return 0; err: return 1; }