ページ 11

swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月16日(土) 22:29
by bonbo
早速ですが質問させていただきます。
以前Xcodeにてswprintf(wchar_t,size_t,const wchar_t*,...)が成功しない(ただし第三引数にはワイド文字が含まれている)
ことについて質問させていただいたのですが、その時は

コード:

setlocale(LC_CTYPE,"UTF-8");
を事前に追加することで解決したのですが、
実機で試してみるとなぜか成功しません。何がいけないのでしょうか。

実際に問題になる個所は

コード:

wchar_t test[256];
    setlocale(LC_CTYPE,"UTF-8");
    NSLog(@"%d",swprintf(test,256,L"りんご"));//ワイド文字が入ると失敗する(-1が返ってくる)
短いのですが、一応記載しておきます。シミュレーターでは成功します(3が返ってくる)。

環境はXcode4.4
今まで使っていたのはiPhone5.1simulator
テストに使っている機種はiPhone4S(それ以外の機種ではテストしておりません。持っていないので…)
です

ソースコード等をアップロードしておきます。キーワードは"test"です
http://www1.axfc.net/uploader/so/2796058
(これのinitWithCoder内に記述しています)

分かりにくい説明で申し訳ありません。

よろしくお願いします。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月16日(土) 23:04
by h2so5
Xcode 4.5.1 + iPhone 6.0 simulator では動きませんでした。swprintfが -1 を返します。
ちょっと調べたところ簡単な解決法は無さそうなので、
swprintf を使わずに NSString stringWithFormat: を使ったほうが早いと思います。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月16日(土) 23:41
by bonbo
>h2so5さん
ありがとうございます。
>swprintf を使わずに NSString stringWithFormat: を使ったほうが早いと思います。
つまり

コード:

wchar_t* wc[256];
NSString *str ;
const char *coc;
str = [NSString stringWithFormat:@"%@", @"りんご"];
coc = [str UTF8string];
mbstowcs(wc,coc,256);

こういうことでしょうか。mbstowcsは使ったことがなかったので、もしかしたら間違っているかもしれませんが。
原因が気にはなりますが、確かにこれで代用することができますね。

動作を確認してきます。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月16日(土) 23:56
by bonbo
>NSString *str = [ [ NSString alloc ] initWithUTF8String:str ];
なんでconstに代入しようとしてるんだ全く…

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月16日(土) 23:59
by bonbo
引用箇所まで間違えてしまいました..
const char *coc;

char *coc;

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月17日(日) 12:50
by bonbo
一応試しましたが、mbstowcsやwcstombsも-1を返してきました。
マクロの書き換えでLを@に変え、wchar_tをNSStringに書き換えて再度試してみます。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月17日(日) 17:39
by ISLe
コードベースの指定は"UTF-8"ではなく、".UTF-8"が正しいような気がしますけど。
あるいは地域も含めて"ja_JP.UTF-8"とか。

環境に依存するのでiOSがどういう文字列なら正しく解釈するかは分かりませんけど。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月18日(月) 10:17
by bonbo
>ISLeさん
ありがとうございます。
>コードベースの指定は"UTF-8"ではなく、".UTF-8"が正しいような気がしますけど。
>あるいは地域も含めて"ja_JP.UTF-8"とか。
どれも認識してくれませんね…Macのデベロッパーフォーラムでも質問してみます。

とりあえず現状ですが、wchar_tからNSStringへの変換方法が実質無い(wchar_tから他への変換方法が無い)
ということが分かりました。UTF-8を認識するようにできていないのでしょうか。

大量のwchar_t用の関数をNSString用に書き直す作業で泣きそうです。

何か解決策が見つかりましたら来ます。

ありがとうございました。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月18日(月) 11:13
by h2so5
UNIX系では wchar_t の中身は UTF-8 ではなく UTF-32 です。
ちなみにWindowsだと UTF-16 です。

コード:

wchar_t utf32[256] = L"素数りんご";

NSData *data = [[NSData alloc] initWithBytes:utf32 length: sizeof(utf32)];
const NSString *str = [[NSString alloc] initWithData:data encoding: NSUTF32LittleEndianStringEncoding];

NSLog(@"%@", str);
Windowsソースを流用したいときはコンパイラのオプションで -fshort-wchar を指定して wchar_t を16bit にする手もあります。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月18日(月) 17:35
by ISLe
wchar_tは特定のコードセットを前提にしてはいけませんし、UTF-8はマルチバイト文字セットなのでwchar_tで扱いませんし、ロケールの設定は外部とのやり取りをUTF-8で行うという話だと思ってました。

(追記)
こんなページを見付けました。
FreewareDevForMac: Development Tips
SJISの文字列を文字化けしないようにNSString型変数に格納したい | Programming iPhone,iPad,Objective-C and Mac プログラミングはロケンロールだ

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月18日(月) 18:54
by bonbo
>h2so5さん
ありがとうございます。
できました。
こんな方法があったのですね..
何も考えずにUTF-8でやっていました。

>ISLeさん
ありがとうございます。
>wchar_tは特定のコードセットを前提にしてはいけませんし
環境によって使えなくなるのはしょうがないのですね…
>http://imprinter.blogspot.jp/2005/12/de ... -tips.html
ここでやっているのも結局mbstowcsを使っているので、できませんでした…swprintfと同様の症状で..
>http://morrydtm.wordpress.com/2012/01/0 ... ring型変数に格/
これがh2so5さんがおっしゃっていた方法ですね。ありがとうございます。
やはり検索力不足です。すみません。


みなさんありがとうございました。

Re: swprintf(wchar_t,size_t,const wchar_t*,...)が実機で成功しない

Posted: 2013年2月18日(月) 21:38
by ISLe
海外のフォーラムの記事とか読んでみましたが、iPhoneだとwchar_t=UTF-32という前提で書くしかないみたいですね。

組み込み系にはよくあることですが。
#Androidでもwcharは使えないとか。