[C言語]UTF-8でエンコードされた文字列の部分文字列を取り出すコード

C言語のstrncpy関数やmemcpy関数ではバイト単位の操作になるので、漢字、ひらがな、カタカナなどの全角文字を文字数で指定して部分文字列を取り出すことができません。 そこで半角英数も全角文字も1文字として部分文字列を取り出すことができる関数を作成します。

以下はそのコードです。[C言語]UTF-8でエンコードされた文字列の文字数を取得するコードと同様に、文字の1バイト目のビットの状態を調べることによってその文字が何バイト文字を判定しています。

#include <stdio.h>
#include <string.h>

char *substr_utf8(char *dest, char *src, int offset, int len);
int _bytesize(unsigned char code);


int main(void)
{
    char *testStr = "ABCDEFGあいうえおアイウエオ愛夢佐々木";
    char strBuf[256];

    memset(strBuf, 0sizeof strBuf);

    printf("substr_utf8($testStr, 0, 5) = %s\n", substr_utf8(strBuf, testStr, 05));
    printf("substr_utf8($testStr, 3, 3) = %s\n", substr_utf8(strBuf, testStr, 33));
    printf("substr_utf8($testStr, 10, 4) = %s\n", substr_utf8(strBuf, testStr, 104));
    printf("substr_utf8($testStr, 13, 5) = %s\n", substr_utf8(strBuf, testStr, 135));

    return 0;
}

/* UTF-8でエンコードされた文字列の部分文字列を取り出す */
/* substr_utf8 (文字列式, オフセット, 長さ)*/
char *substr_utf8(char *dest, char *src, int offset, int len)
{
    int srclen = strlen(src);
    int pos = 0;
    int count = 0;
    char *cp = dest;

    while (pos < srclen) {
        unsigned char code;
        code = *(src + pos); /* ASCIIコード値を取得 */
        int bytelen = _bytesize(code);

        if (count >= offset && count < (offset + len)) {
            memcpy(cp, (src + pos), bytelen);
            cp += bytelen;
            *cp = '\0';
        }
        pos += bytelen;
        count++; /* 文字数をカウント */
    }

    return dest;
}

/* 文字のバイト長を求める */
int _bytesize(unsigned char code)
{
    int size = 1;
    int i;

    if (0x80 & code) { /* 1バイト文字以外 */
        for (i = 2; i <= 8; i++) {
            code <<= 1;
            if (!(0x80 & code)) {
                break;
            }
            size++;
        }
    }
    return size;
}

実行結果
$ ./substr_utf8
substr_utf8($testStr, 0, 5) = ABCDE
substr_utf8($testStr, 3, 3) = DEF
substr_utf8($testStr, 10, 4) = えおアイ
substr_utf8($testStr, 13, 5) = イウエオ愛

[2324] Posted by kagahiro at 2013/07/02 11:02:48
オープン | 0 point | Link (3) | Trackback (0) | Comment (0)

キーワード

C言語 サンプル プログラム プログラミング UTF8 substr 文字列 

ジャパンのホームページ


[C言語]UTF-8でエンコードされた文字列の部分文字列を取り出すコード 関連リンク

[C言語]UTF-8でエンコードされた文字列の文字数を取得するコード
C言語のstrlen関数では文字列の長さとして返ってくる値はバイト単位となるので、UTF-8でエンコードされている場合、漢字、ひらがな、カタカナなどは1文字で3となってしまいます。We...
[Perl]UTF-8でエンコードされた文字列の部分文字列を取り出すコード
Perlのsubstr関数ではバイト単位の操作になるので、漢字、ひらがな、カタカナなどの全角文字を文字数で指定して部分文字列を取り出すことができません。それでは不都合なことも多いので、半角英数も全角文字も1文字と...
[C言語]1バイト(8bit)の10進数を2進数の文字列に変換するコード
1バイト(8bit)の10進数を2進数の文字列に変換するコードのC言語版です。C言語では、PerlやPHPなどのように2進文字列に変換してくれる便利な関数は関数はないので、ビット演...

[C言語]UTF-8でエンコードされた文字列の部分文字列を取り出すコード トラックバック

トラックバックURL :


[C言語]UTF-8でエンコードされた文字列の部分文字列を取り出すコードへのコメント


詳細の入力フィールドを表示する

おすすめ  (チェックしてコメントすると最新情報に掲載)
コメント :

< 前の投稿      次の投稿 >

アクセスランキング

今日のアクセスランキング TOP 10

  1. 有力将棋系ユーチューバーのショウヤンさんが将棋ウォーズで「ソフト指し」を告白し衝撃走る (3 PV)
  2. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (2 PV)
  3. ようつべ (YouTube) 動画のダウンロードと保存 (2 PV)
  4. ウェブページを1回だけリロード(再表示)する方法 (1 PV)
  5. [将棋]角換わり▲4五桂速攻(△6五桂速攻) #佐藤天彦名人 #三浦弘行九段 (1 PV)
  6. Google Analytics(グーグルアナリティクス) - 無料アクセス解析サービス (1 PV)
  7. FC2動画やYouTubeなどから無料動画(映画やドラマ、アニメ、音楽など)を探す方法 (1 PV)

今月のアクセスランキング TOP 10

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (2288 PV)
  2. 最新のGoogle News(グーグルニュース)日本版のRSSが取得できるURL (1678 PV)
  3. Google News (グーグルニュース)日本版 (1631 PV)
  4. Tumblr(タンブラー)のダッシュボードからおすすめ投稿を消す(非表示にする)方法 (391 PV)
  5. 有力将棋系ユーチューバーのショウヤンさんが将棋ウォーズで「ソフト指し」を告白し衝撃走る (369 PV)
  6. [将棋]角換わり▲4五桂速攻(△6五桂速攻) #佐藤天彦名人 #三浦弘行九段 (257 PV)
  7. [Perl]UTF-8でエンコードされた文字列の文字数を取得するコード (236 PV)
  8. ウェブページを1回だけリロード(再表示)する方法 (203 PV)
  9. グーグルニュース(Google News)日本版が表示できるURL (142 PV)
  10. USTREAM(ユーストリーム) 日本語版 無料のライブ映像配信サービス (141 PV)

アクセス統計

ディレクトリ

関連サイト