Seeker's Memo

個人的で技術的かもしれないメモがメインのブログです。http://seekers.hatenablog.jp/about

マルチバイトとワイドの文字列変換サンプル(ほとんどC言語)

内容は表題の通り。まあできる人にとっちゃ、こんなの朝飯前なのかもしれませんがとりあえず自分用にメモしてみる。
コメントを結構端折ってるのでわかりにくいかも・・・(後で自分で読解するにしても
C++で書いてあるけど、C++である必要が感じられないw
localeのところはC関数のsetlocaleにして、あとはちまちまnamespaceを剥いでiostreamを抜けばC言語になりますな…。
SJISとかサロゲートペアとかは考慮してない。
※以下のソースを利用したことによる影響の責任は一切取りません。一応テストはしたけどきちんと動く保証もないです。


#include <iostream>
#include <cstring>
#include <cstdlib>


//マルチバイトの文字列cstrからワイド文字列に変換しtgt_strに格納する。
//len == cstrに対する最大文字数(NUL文字を含む)
wchar_t* mbstr_to_widestr(wchar_t* wstr, char* mbstr, const size_t len){
	int i = 0; //wstr[i]
	int k = 0; //mbstr[k]
	while(k < len){
		int mlen = std::mblen(&mbstr[k], len);
		if(mlen > 0){
			mbtowc(&wstr[i], &mbstr[k], mlen);
			k += mlen;
			++i;
			continue;
		}
		else if(mlen == 0){
			wstr[i] = L'\0';
			break;
		}
		else{
			++k;//変換できなかったので1文字飛ばす
			continue;
		}
	}
	return wstr;
}

char* widestr_to_mbstr(char* mbstr, wchar_t* wstr, const size_t len){
	int i = 0; //mbstr[i]
	int k = 0; //wstr[k]
	while(k < len){
		int wlen = wctomb(&mbstr[i], wstr[k]);
		if(wlen > 0){
			i += wlen;
			++k;
			continue;
		}
		else if(wlen == 0){
			mbstr[i] = '\0';
			break;
		}
		else{
			k++;//変換できなかったので一文字飛ばす
			continue;
		}
	}

	return mbstr;
}


int main(const int argc, char **argv){
	std::locale::global(std::locale(""));
#ifdef __TO_WIDECHAR
    char mbstr[] = "日本語表示で、[Hello,World!!]"; 
	wchar_t wbuff[256];
	mbstr_to_widestr(wbuff, mbstr, std::strlen(mbstr)+1);
	wprintf(L"(Wide)==%ls\n", wbuff);
#endif
#ifndef __TO_WIDECHAR
	char mbbuff[256];
	wchar_t wstr[] = L"日本語表示で、[Hello, World!!]";

	widestr_to_mbstr(mbbuff, wstr, std::wcslen(wstr)+1);
	
	printf("(Multi)==%s\n", mbbuff);
#endif

	return 0;
}