[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. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (2 PV)
  2. DeepMind(ディープマインド)社が「AlphaGo: 学習ツール」を公開 #機械学習 (2 PV)
  3. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (2 PV)
  4. Google News (グーグルニュース)日本版 (2 PV)
  5. [将棋]宮田敦史六段が居飛車で久保利明王将の卑怯な振り飛車戦法に圧勝 #NHK杯 (1 PV)
  6. Yahoo! JAPAN(ヤフージャパン) (1 PV)
  7. [将棋]動画配信やライブ配信を行っているおすすめの将棋系ユーチューバー(YouTuber)チャンネル (1 PV)
  8. [囲碁]引退した囲碁AI「AlphaGo(アルファ碁)」が50局の「セルフ対局」棋譜を公開 #機械学習 (1 PV)
  9. グーグルニュース(Google News)日本版が表示できるURL (1 PV)
  10. ようつべ (YouTube) 動画のダウンロードと保存 (1 PV)

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

  1. SQLのSELECT文で先頭から上位(TOP)10件のレコードを取得する方法(SQL Server、Oracle、MySQL、PostgreSQL) (1719 PV)
  2. グーグルニュース(Google News)日本版が表示できるURL (681 PV)
  3. Google News (グーグルニュース)日本版 (236 PV)
  4. DeepMind(ディープマインド)社が「AlphaGo: 学習ツール」を公開 #機械学習 (217 PV)
  5. Google Finance(グーグルファイナンス)- リアルタイム株価情報、金融ニュース、日本株 (182 PV)
  6. [将棋]将棋実況ユーチューバーのクロノさんが朝日新聞のクレームで棋譜中継を配信中止 (156 PV)
  7. フリーソフトウェア/オープンソースのタブー (128 PV)
  8. [食べ物]七草粥(ななくさがゆ) (117 PV)
  9. [将棋]竜王戦第三局は居飛車振り飛車の対抗型で丸山忠久九段が勝利 #竜王戦 (104 PV)
  10. USTREAM(ユーストリーム) 日本語版 無料のライブ映像配信サービス (96 PV)

アクセス統計

ディレクトリ

関連サイト