#はじまり
知っている方も多いと思いますが・・・
データの領域に制限があって、NSString 型の文字列 を char 型にして格納
あとでそのデータをNSString型に戻して表示するようにしたら、nullになった。
#例)
たとえばこれ
環境
Xcode 7.2
char str[16];
NSString *nStr1=@"12345678あいうえおか";
memset( str, 0, 16);
memcpy( str, [nStr1 UTF8String],15);
// char変換
NSString *nStr2=[NSString stringWithUTF8String:str];
NSLog(@"[%@]=>[%@]",nStr1,nStr2);
[12345678あいうえおか]=>[(null)]
まぁブッタ切るから、最後のほうの文字が化けるのは仕方ないと思っていましたが、
せめて 12345678は、ASCII文字なんだから変換してくれるだろう・・・・と
結果は、期待を裏切って null 全く遠慮がないですね。 気持ちいいくらい スパーと nullです。
プログラム間違えてんじゃないの・・・・・と思ってました。
#分析
Googleさんに聞いても基本は正しいようですが、それ以上は・・・どう聞けば良いのやら( キーワードが・・・・)適当に検索したが、発見できず・・・
自力でなんとかする事となる。
実験で
・*nStr1を全部ASCIIにしたらOK
・length(15) を変更するとOKの場合がある
から、ぶったぎったらnullになるようです(一番いやな結果となりました)
#対策
見たくないUTF8について調べると、ASCII以外は、複数バイトで構成されていて、2〜6バイトで表現されるようです。(なんて面倒なコードなんでしょ 1文字6バイトって何? 200文字で1Kbyte超えるじゃん )
資料参考に関数作りました。
(参考;https://www.ietf.org/rfc/rfc2279.txt)←英語なんですよー
https://tools.ietf.org/html/rfc3629#page-4←やっぱり英語なんですね
2279→3269で変更があったようですね
https://www.akanko.net/marimo/data/rfc/rfc3629-jp.txt
日本語でかかれてる。
UInt8は、最近 char型で、ひどい目にあったから使いました。( charでも問題ないでしょう )
void char2Utf8Limit(UInt8 *ptr ,short len)
{
UInt8 *nxt=ptr;
UInt8 *cur=ptr;
while( nxt < (ptr+len) )
{
cur=nxt;
if( (*nxt & 0xFE)==0xFC ) nxt=nxt+6;
else if( (*nxt & 0xFC)==0xF8 ) nxt=nxt+5;
else if( (*nxt & 0xF8)==0xF0 ) nxt=nxt+4;
else if( (*nxt & 0xF0)==0xE0 ) nxt=nxt+3;
else if( (*nxt & 0xE0)==0xC0 ) nxt=nxt+2;
else nxt=nxt+1;
}
while( cur<(ptr+len) )
{
*cur++=0;
}
}
// char変換
を
// char変換
char2Utf8Limit( (UInt8*)str, 15 );
にする
[12345678あいうえおか]=>[12345678あい]
当初の予定よりも文字数が短いのですが、原因は切り口でした。
ところで、エンディアンとかは、考えてなくて作ったんですが、良いのだろうか?