このページの内容

v2.4.0, June 2026

はじめに

Cプログラム向けの基本的な動的文字列マクロが、uthashの utstring.h に含まれています。自分のCプログラムで使うには、utstring.h をソースディレクトリにコピーし、プログラムで使用するだけです。

#include "utstring.h"

動的文字列は、データの挿入、連結、長さと内容の取得、部分文字列の検索、内容の消去などの操作をサポートします。utstringにはバイナリデータも格納できます。文字列の操作を下に示します。

utstringの操作の一部は、マクロではなく関数として実装されています。

ダウンロード

ヘッダーファイル utstring.h をダウンロードするには、https://github.com/troydhanson/uthash のリンクからuthashをクローンするかZIPファイルを取得し、src/ サブディレクトリを確認してください。

BSDライセンス

このソフトウェアは修正版BSDライセンスで提供されています。自由に利用できるオープンソースソフトウェアです。

プラットフォーム

utstring マクロは、次の環境でテストされています。

  • Linux,

  • Windows(Visual Studio 2008およびVisual Studio 2010を使用)

使い方

宣言

動的文字列自体のデータ型は UT_string です。次のように宣言します。

UT_string *str;

作成と解放

次に、utstring_new で文字列を作成します。使用を終えたら、utstring_free で文字列とその内容をすべて解放します。

操作方法

utstring_printf または utstring_bincpy の操作で、文字列にデータを挿入(コピー)します。utstringを別のutstringに連結するには utstring_concat を使います。文字列の内容を消去するには utstring_clear を使います。文字列の長さは utstring_len で、内容は utstring_body で取得できます。後者は char* と評価されます。このポインターが指すバッファーは常にヌル終端されています。そのため、文字列を受け取る外部関数に直接渡せます。自動的に付加されるこの終端ヌル文字は、文字列の長さには含まれません。

使用例

次の例でutstringの使い方を示します。

使用例1

#include <stdio.h>
#include "utstring.h"

int main() {
    UT_string *s;

    utstring_new(s);
    utstring_printf(s, "hello world!" );
    printf("%s\n", utstring_body(s));

    utstring_free(s);
    return 0;
}

次の例では、utstring_printf が文字列に追記することを示します。連結の例も示しています。

使用例2

#include <stdio.h>
#include "utstring.h"

int main() {
    UT_string *s, *t;

    utstring_new(s);
    utstring_new(t);

    utstring_printf(s, "hello " );
    utstring_printf(s, "world " );

    utstring_printf(t, "hi " );
    utstring_printf(t, "there " );

    utstring_concat(s, t);
    printf("length: %u\n", utstring_len(s));
    printf("%s\n", utstring_body(s));

    utstring_free(s);
    utstring_free(t);
    return 0;
}

次の例は、文字列にバイナリデータを挿入する方法を示します。また、文字列の内容を消去して、新しいデータを書き込んでいます。

使用例3

#include <stdio.h>
#include "utstring.h"

int main() {
    UT_string *s;
    char binary[] = "\xff\xff";

    utstring_new(s);
    utstring_bincpy(s, binary, sizeof(binary));
    printf("length is %u\n", utstring_len(s));

    utstring_clear(s);
    utstring_printf(s,"number %d", 10);
    printf("%s\n", utstring_body(s));

    utstring_free(s);
    return 0;
}

リファレンス

以下はutstringの操作です。

操作

utstring_new(s)

新しいutstringを割り当てる

utstring_renew(s)

sが NULL なら新しいutstringを割り当て、それ以外なら内容を消去する

utstring_free(s)

割り当て済みのutstringを解放する

utstring_init(s)

utstringを初期化する(構造体自体は割り当てない)

utstring_done(s)

utstringの内部メモリーを解放する(構造体自体は解放しない)

utstring_printf(s,fmt,…)

utstringに書式付きで書き込む(追記)

utstring_bincpy(s,bin,len)

長さlenのバイナリデータを挿入する(追記)

utstring_concat(dst,src)

srcのutstringをdstのutstringの末尾に連結する

utstring_clear(s)

sの内容を消去する(長さを0にする)

utstring_len(s)

sの長さを符号なし整数として取得する

utstring_body(s)

sの内容への char* を取得する(バッファーは常にヌル終端されている)

utstring_find(s,pos,str,len)

posから順方向に部分文字列を検索する

utstring_findR(s,pos,str,len)

posから逆方向に部分文字列を検索する

new/freeとinit/doneの違い

新しい文字列を割り当てたり解放したりするには、utstring_new と utstring_free を使います。UT_stringを静的に割り当てている場合は、utstring_init と utstring_done で内部メモリーを初期化したり解放したりします。

utstring内の部分文字列を検索するには、utstring_find と utstring_findR を使います。順方向と逆方向の検索が用意されています。逆方向の検索は、文字列の末尾から先頭方向へ走査します。これらは検索開始位置を受け取り、その位置は0(utstringの先頭)を基準に数えます。負の位置は文字列の末尾から数えるため、-1は最後の位置です。逆方向の検索では、開始位置が検索対象の部分文字列の末尾、たとえば cat の t に対応することに注意してください。返り値は常に、utstring内で部分文字列が始まる位置のオフセットを示します。一致する部分文字列が見つからない場合は、-1を返します。

たとえば、s というutstringに次の内容が入っているとします。

ABC ABCDAB ABCDABCDABDE

このとき、ABC を順方向および逆方向に検索すると、次の結果になります。

utstring_find(  s, -9, "ABC", 3 ) = 15
utstring_find(  s,  3, "ABC", 3 ) =  4
utstring_find(  s, 16, "ABC", 3 ) = -1
utstring_findR( s, -9, "ABC", 3 ) = 11
utstring_findR( s, 12, "ABC", 3 ) =  4
utstring_findR( s,  2, "ABC", 3 ) =  0

これまでの例は、内部のKnuth-Morris-Pratt(KMP)テーブルを内部で構築し、検索後に解放する「一度だけ使う」部分文字列検索です。ある部分文字列を何度も検索する必要がある場合は、KMPテーブルを保存して再利用する方が効率的です。

KMPテーブルを再利用するには、手動で構築してから内部の検索関数に渡します。使用する関数は次のとおりです。

_utstring_BuildTable  (順方向検索用のKMPテーブルを構築する)
_utstring_BuildTableR (逆方向検索用のKMPテーブルを構築する)
_utstring_find        (構築済みのKMPテーブルで順方向検索する)
_utstring_findR       (構築済みのKMPテーブルで逆方向検索する)

次は、部分文字列「ABC」の順方向検索用KMPテーブルを構築し、検索で使う例です。

long *KPM_TABLE, offset;
KPM_TABLE = (long *)malloc( sizeof(long) * (strlen("ABC")) + 1));
_utstring_BuildTable("ABC", 3, KPM_TABLE);
offset = _utstring_find(utstring_body(s), utstring_len(s), "ABC", 3, KPM_TABLE );
free(KPM_TABLE);

内部の _utstring_find の第2引数は、開始位置ではなくUT_stringの長さであることに注意してください。文字列の先頭アドレスに位置を加え、その長さから同じ位置を引くことで、位置パラメーターに相当する動作を実現できます。

注意事項

  1. メモリー不足時の既定の処理(exit(-1) を呼び出す動作)を変更するには、utstring_oom() マクロを utstring.h のインクルード前に定義し直してください。たとえば、次のようにします。

    #define utstring_oom() do { longjmp(error_handling_location); } while (0)
    ...
    #include "utstring.h"