JFP 開発ガイド

汎用コード変換

汎用コード変換の API表 4-2 のとおりです。変換前エンコーディングと変換後エンコーディングを指定する名称と指定の意味については iconv_ja(5) のマニュアルページ、および『JFP ユーザーズガイド』の第 6 章「フィルタを用いたコード変換」を参照してください。

表 4-2 汎用コード変換 API

インタフェース名

作用

iconv_open()

変換元コードと変換先コードから変換に必要な情報を得る 

iconv()

得られた情報をもとに実際の変換を行う 

iconv_open()

変換に必要だった情報を解放する 

プログラム例

例 4-2 では iconv() インタフェースを用いて iconv(1) コマンドのサブセットに相当するフィルタを作成します。これらの API を使用する場合は、iconv.h ヘッダファイルを取り込むことが必要です。一般的な国際化 API と異なり、iconv() では、変換前、変換後のそれぞれの文字集合およびエンコーディングに関する情報を変換記述子を通して入手します。したがって、次のプログラム例でも setlocale()が呼び出されていないことに注意してください。


例 4-2 汎用コード変換

sun% cat my_iconv.c

/*
 * Read lines from a stdin and convert the encoding.
 * It is assumed that each line has at most BUFSIZ - 1
 * byte length.
 * Both of source and destination encodings are passed
 * from the command line.
 *
 * Note:        Calling iconv() itself doesn't need to call
 *              setlocale() in advance.
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <iconv.h>
int
main(int argc, char *argv[])
{
        iconv_t icv_hook;
        char in_buf[BUFSIZ];
        char out_buf[BUFSIZ];
        char *inp;
        char *outp;
        char *from_code;
        char *to_code;
        extern char *optarg;
        extern int optind;
        size_t ret_val;
        size_t in_buf_left;
        size_t out_buf_left;
        int i;
        
        if (argc != 5) {
                fprintf(stderr, "usage: %s -f  -t ¥n", argv[0]);
                exit(-1);
        }
        while ((i = getopt(argc, argv, "f:t:")) != EOF) 
                switch (i) {
                case `f':
                        from_code = optarg;
                        break;
                case `t':
                        to_code = optarg;
                        break;
                default:
                        fprintf(stderr, "usage: %s -f  -t ¥n", argv[0]);
                        exit(-1);
                }
        icv_hook = iconv_open(to_code, from_code);
        if (icv_hook == (iconv_t)-1) {
                perror("iconv_open()");
                exit(-1);
        }
        

        i = 0;
        while(fgets(in_buf, BUFSIZ, stdin) != NULL){
                if (!in_buf[0]) {
                        perror("fgets()");
                        exit(-1);
                }
                i++;
                memset(out_buf, 0, BUFSIZ);
                in_buf_left = strlen(in_buf);
                out_buf_left = BUFSIZ;
                inp = in_buf;
                outp = out_buf;
                errno = 0;
                ret_val = iconv(icv_hook,
                                (const char **)inp, in_buf_left, outp, out_buf_left);
                if (ret_val == (size_t)-1) {
                        if (errno == EILSEQ)
                                perror("EILSEQ");
                        else if (errno == E2BIG)
                                perror("E2BIG");
                        else if (errno == EINVAL)
                                perror("EINVAL");
                        fprintf(stderr, "Line number is %d¥n", i);
                        exit(-1);
                }
                write(STDOUT_FILENO, out_buf, (BUFSIZ - out_buf_left));
        }
        iconv_close(icv_hook);
        return(0);
}
sun% cat file3
新しいシステム*は現在のネットワーク*環境を変えることなく
インターネット*とのシームレス*な接続を可能にします。また
セキュリティ*の問題も新しい認証テクノロジー*を用いることで
アドミニストレータ*の負担を減らしています。
sun% cc -o my_iconv my_iconv.c
sun% cat file3 | ./my_iconv -f eucJP -t PCK | ./my_iconv -f PCK -t eucJP
新しいシステム*は現在のネットワーク*環境を変えることなく
インターネット*とのシームレス*な接続を可能にします。また
セキュリティ*の問題も新しい認証テクノロジー*を用いることで
アドミニストレータ*の負担を減らしています。
                


注意 - 注意 -

* の部分のカタカナは、半角カタカナになります。