プログラミング iconv サンプルコード

なぜかiconvのサンプルプログラムがweb上になかなか転がっていなかったので、
書いてみる。
Shift_JISのファイルを引数にとり、
UTF-8のファイルを吐く。
iconv_open("UTF-8", "Shift_JIS")の引数は
実装依存
hp-uxではShift_JISではコンパイル時に失敗。

#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>

#define S_SIZE (86243)

int main(char argc, char *argv[])
{
	int i;

	FILE *src, *dst;

	src = fopen(argv[1], "r");
		if(!src){
			perror(argv[i]);
			exit(EXIT_FAILURE);
		}
		
	dst = fopen("utf8.text", "w");
		if(!dst){
			perror("utf8.text");
			exit(EXIT_FAILURE);
		}

	iconv_t cd;

	if((cd = iconv_open("UTF-8", "Shift_JIS")) == (iconv_t)-1){
		perror("iconv_open");
		exit(EXIT_FAILURE);
	}

	char inbuf[S_SIZE];
	char *inchar;
	char outbuf[S_SIZE];
	char *outchar;
	size_t outbytesleft;
	size_t inbyteleft;

	int bytesread;
	size_t ret_val;

	inbyteleft = 0;

	for(;;){

		inchar = inbuf;
		outchar = outbuf;

		outbytesleft = S_SIZE;

		if((bytesread = read(fileno(src), inbuf+inbyteleft,
						(size_t)S_SIZE-inbyteleft)) < 0){
			perror("read");
			exit(EXIT_FAILURE);
		}
	

		if(!(inbyteleft += bytesread)){
			break;
		}

		ret_val = iconv(cd, &inchar, &inbyteleft, &outchar, &outbytesleft);

		if(write(fileno(dst), outbuf, (size_t)S_SIZE-outbytesleft)<0){
			perror("write");
			exit(EXIT_FAILURE);
		}

		if ((ret_val == -1) && (errno == EINVAL)) {
			perror("convert1");
			exit(EXIT_FAILURE);
		}

  		if ((ret_val == -1) && (errno == EILSEQ)) {
			perror("convert2");
			exit(EXIT_FAILURE);
		}

		if ((ret_val == -1) && (errno == E2BIG)) {
			perror("convert3");
			exit(EXIT_FAILURE);
		}
	}

        if(iconv_close(cd) == -1){
                perror("CLOSE");
                exit(EXIT_FAILURE);
        }


	exit(EXIT_SUCCESS);
}

gcc iconv.c -L/usr/local/lib -liconv
コンパイル
ちなみに、バッファが足りないと
Arg list too long
という頓珍漢なエラーを出して失敗するよ。