2011年09月02日

NSStringとC文字列(1)

Mac OS XでもiOSでも同じですが、Cocoaで文字列を扱う場合には、NSString系のクラスを使います。ですが、通信処理やC言語由来のライブラリを使いたい時など、場合によってはC言語の形式の文字列が必要になる場合があります。

そのために、NSString から C文字列、あるいはC文字列からNSStringへの変換をする必要があります。

今回はその方法についてメモしておきます。

■NSStringからC文字列を取り出す。

いくつか方法がありますが、一番お手軽なのは


- (const char *)UTF8String;


これを呼べばNULL文字終端のC文字列が戻り値で得られます。その場でなにかして終わりという場合には一番簡単です。

文字列の保存されているメモリ領域はNSStringが内部的に確保してくれて自動的に開放されます。が、この開放タイミングがよくわかりません。ですから、c文字列を取り出した後保持しておきたいとかしばらくたってから使うという場合には、別に領域を確保してそこに複製します。

ちなみにリファレンスでは以下。


The returned C string is automatically freed just as a returned object would be released; you should copy the C string if it needs to store it outside of the autorelease context in which the C string is created.


C文字列が生成されたオートリリースプールコンテキストの外に出たら自動的に開放されるよと。いうことになっています。このC文字列を保持するためのなんらかのコンテイナオブジェクトが存在していてそれが、プログラマ側に見えていないだけってことでしょうか?



const char *temp = [theString UTF8String];
size_t size = strlen(temp) + 1;
char *buff = malloc(size);
strlcpy(buff,temp,size);


ただし、このメソッドではUTF8でしか取り出せません。JISとかSJISとかの他の文字列エンコーディングで取り出したい場合には別のメソッドを使います。


- (const char *)cStringUsingEncoding:(NSStringEncoding) encoding;


こちらは文字列エンコーディングを指定して変換する。主な日本語文字エンコーディングは以下。他にもあるので必要ならリファレンスを見てください。


NSShiftJISStringEncoding
NSISO2022JPStringEncoding
NSJapaneseEUCStringEncoding
NSUTF8StringEncoding
NSUnicodeStringEncoding


こちらは、文字列変換時に失敗する場合の注記があります。NSStringは内部的にユニコードで保持しているので、文字によってはシフトJISにないものがあるなど変換に失敗する可能性があるためです。その場合にはNULLが戻るので変換結果は必ずチェックする必要があります。

失敗してもいい場合はlossyデータとして別のメソッドを使って変換することになっています。

また、こちらのC文字列もNULL終端されていますがその領域確保についてはUTF8Stringとは違う記述になっています。


The returned C string is guaranteed to be valid only until either the receiver is freed, or until the current autorelease pool is emptied, whichever occurs first.


オートリリースプールのコンテキストの外側では開放されるので、それ以上のライフタイムを持たせたい場合には別メモリを確保してそこにコピーしないさいということです。が、こちらは自分でfreeしてもいいことになっています。そんなことが可能なんでしょうか?



なんだか長くなってきたので、何回かに分けることにします。本当に書きたいことはこの後なんだけどなあ。
posted by 永遠製作所 at 18:01| 東京 ☀| Comment(0) | TrackBack(0) | Cocoa | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/223881312
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック