
「たのしいCocoaプログラミング[Leopard対応版]」を元に、要約メモしておきたいと思います。
文字列
文字列のためのクラス
Cocoa では文字列のためのクラスを独自に用意している。
NSString と NSMutableString
NSString クラスは内容を変更しない文字列を表す。NSMutableString は内容を変更できる文字列。NSString は一度インスタンスを作成するとテキストを変更できないので、ウィンドウのタイトルを取得するときやボタンのタイトルを取得するときに使う。
テキストエンコーディング
■ NSString の文字コードは Unicode
NSString も内部に保持する文字列のコードとして Unicode を使っているので、英語も日本語も NSString で表現することが可能。
文字列の作成
■ @”" を使った作成
C言語とは1箇所だけ異なり、ダブルクォーテーションの前に @ を付ける。これが付くと、C言語の文字列、つまり char の配列ではなく、NSString のインスタンスになる。
1 2 3 4 | // C文字列 char* cString = "This is C string"; // NSString インスタンス NSString* string = @"This is NSString"; |
■ 日本語文字列からの作成
@ を使った NSString の作成は、アルファベットでしか使えない。日本語文字列を使う目的がウィンドウのタイトルやボタンに表示する文字列の場合は、外部ファイルにその文字列を書いて適時読み込んで文字列を得るようにした方が、日本語以外の言語にローカライズする時の柔軟性が増す。 ただ、デバッグなどで日本語を使いたい場合には、C言語の文字列から NSString インスタンスと作るメソッドstringWithCString:encodeing: 、または initWithCString:encoding を使う。
NSString
1 2 3 4 5 | + (id) stringWithCString:(const cha*)cString encoding:(NSStringEncoding)encoding - initWithCString:(const char*)cString encoding:(NSStringEncoding)encoding C言語の文字列 cString と、そのテキストエンコーディング encoding を指定して、インスタンスを作る。 |
前者の方は、自動開放されたインスタンスを作成する。後者は alloc の後で呼び出す初期化メソッド。
2つ目の引数にエンコーディングを指定する。「表示 > テキスト > ファイルエンコーディング」メニューで例えば、日本語(Shift JIS)にする。そして、次のようなコードで文字列を作る。
1 2 3 | NSString* jpString; jpString = [NSString stringWithCString:"日本語文字列" encoding:NSShiftJISStringEncoding]; |
C言語の文字列なので、引数の文字列には @ を付けないこと。
この方法はあくまで一時的な回避策として使う。
■ フォーマットからの作成
printf 文で指定するものと同じで置換子を使う、フォーマットを指定して文字列を作成することもできる。
stringWithFormat: というメソッドを使用し、printf と同様に可変引数を使う。
NSString
1 2 3 | + (id) stringWithFormat:(NSString*)format... - (id) initWithFormat:(NSString*)format... フォーマット format を指定して、インスタンスを作る |
フォーマット自体も NSString(つまり @ 付きの文字列)で指定すること。このメソッドで使うことのできる置換子は printf のものとほぼ同じで、さらに NSString のインスタンスも指定できる。下記はよく使う置換子の一覧。
| 置換子 | 説明 |
|---|---|
| %@ | NSString のインスタンス |
| %d、%D、%i | 整数 |
| %u、%U | 符号なしの整数 |
| %x | 符号なしの整数を、小文字の16進数で表現 |
| %X | 符号なしの整数を、大文字の16進数で表現 |
| %f | 小数 |
| %c | 文字 |
| %s | C言語の文字列 |
| %% | %記号そのものを表現 |
下記は使用例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | NSString* stringA; string = @"Mac"; // NSString のインスタンスを指定して、文字列を作る NSString* stringB; stringB = [NSString stringWithFormat:@"%@ Pro", stringA]; NSLog(stringB); // stringB は、"Mac Pro"になる // 整数を指定して文字列を作る int i = 80; NSString* stringC; stringC = [NSStringWithFormat:@"%d%%", i]; NSLog(stringD); // stringD は"0x50"になる |
■ NSRange
NSRange はいろいろなクラスで補助的に使われる構造体。ある範囲を表す。例えば、10文字の文字列を操作するときに「5文字目から3文字分」といったように範囲指定するときに使う。NSRange の定義は以下。
1 2 3 4 | type struct _NSRange { unsigned int location; unsigned int length; } NSRange; |
location と length という2つのフィールドがある。それぞれ、範囲のスタート位置と、長さを表す。NSRange を使うときの便利関数として NSMakeRange というものがある。これを使うと、location と length を指定して NSRange を作ることができる。
NSRange
1 2 | NSMakeRange(unsigned int location, unsigned int length); 範囲のスタート位置 location と、長さ length を指定して、NSRange を作る |
以下はその使用例
1 2 3 | // NSRange を作る NSRange range = NSMakeRange(0,5); NSLog(@"location is %d, length is %d", range.location, range.length); |
文字列の操作
■ 文字列の長さ
文字列の長さを調べるには length メソッドを使う。
NSObject – (unsigned int) length 文字列の長さを、文字数で取得する
length メソッドは言語に関わらず、バイト数ではなく文字数を調べる。使用例は以下。
1 2 3 4 5 6 7 | NSString* string; string = @"Mac OS X"; unsigned int length; length = [string length]; NSLog(@"length is %d", length); // length は8になる |
■ 文字列の連結、挿入、削除
文字列をつないだり一部を変更するためのメソッド。stringByAppendingString:、stringByAppendingFormat: というメソッドを使う。
2つの文字列の連結
ある文字列の後に別の文字列をくっつけて、新しい文字列を作るもの。
NSString
1 2 3 4 | - (NSString*)stringByAppendingString:(NSString*)string 自分自身に、文字列 string を連結した新しい文字列を作成して返す - (NSString)stringByAppendingFormat:(NSString*)format,... 自分自身に、format で指定された文字列を連結した新しい文字列を作成して、返す。 |
使用例は以下
1 2 3 4 5 6 7 8 9 10 11 12 | NSString* stringA = @"Mac OS X"; NSString* stringB = @"Leopard"; // stringA と stringB をつなげる NSString* stringC = [stringA stringByAppendingString:stringB]; NSLog(stringC); // stringC は、"Mac OS X Leopard"となる // stringBに、文字列をつなげる NSString* stringD = [stringB stringByAppendingFormat:@" %d.%d, 10, 5]; NSLog(stringD); // stringD は、"Leopard 10.5"となる |
このメソッドでは、stringA と stringB から、stringC という新しい文字列を作っている。この処理をした後でも stringA と stringB の値は変わらない。似たような方法として、stringWithFormat: メソッドを使ってもいい。
1 2 3 4 | // stringA と stringB から、文字列を作成する NSString* stringE = [NSString stringWithFormat:@"%@%@", stringA, stringB]; NSLog(stringE); // stringE は、"Mac OS X Leopard"となる |
NSMutableString の作成
可変文字である NSMutableString を使う方法もある。一度作ったインスタンスの文字列を変更できる。
NSString
1 2 3 4 5 | + (id) string 空文字列のインスタンスを作る + (id) stringWithString:(NSString*)string - (id) initWithString:(NSString*)string 文字列 string と同じ内容のインスタンスを作る |
string メソッドでは空の文字列を作る。stringWithString: を使えば、NSString から NSMutableString を作ることができる。
1 2 | // 文字列を指定して、NSMutableString を作る。 NSMutableString* string = [NSMutableString stringWithString:@"Mac OS X"]; |
文字列の追加
NSMutableString のインスタンスの後に文字列を追加するには、次のメソッドを使う。
NSMutableString
1 2 3 4 | - (void) appendString:(NSString*)string 文字列 string を追加する - (void) appendFormat:(NSString*)format, ... format で指定された文字列を追加する |
stringByAppendingString: や stringByAppendingFormat: は新しいインスタンスを作るのに対して、こちらはすでにあるインスタンスをそのまま使うことになる。
1 2 3 4 5 6 7 8 9 | // 空文字列を作成する NSMutableString* string = [NSMutableString string]; // 文字列を追加する [string appendString:@"Mac "]; [string appendString:@"OS "]; [string appendString:@"X"]; NSLog(string); // 最終的に文字列は、"Mac OS X"になる |
文字列の挿入
最後だけでなく、好きな箇所に挿入できる。
NSMutableString
1 2 | - (void) insertString:(NSString*)string atIndex:(insigned)index 文字列 string をインデックス index に挿入する |
インデックスを指定するときは、いまある文字列の範囲を超えないように注意。もし越えてしまったら例外と呼ばれるものが発生して、そこで実行がキャンセルされてしまう。使用例は以下。
1 2 3 4 5 6 7 | // 文字列を作成する NSMutableString* string = [NSMutableString stringWithString:@"Mac X"]; // 文字列を挿入する [string insertString:@"OS " atIndex:4]; NSLog(string); // 文字列は、"Mac OS X"になる |
文字列の削除
文字列を削除するのは deleteCharactersInRange: というメソッドを使う。
NSMutableString
1 2 | - (void) deleteCharacterInRange:(NSRange)range 範囲 range で指定した文字列を削除する |
NSRange を使って文字列の範囲を指定する。指定された範囲にある文字列が削除されることになる。
1 2 3 4 5 6 | // 文字列を作成する NSMutableString* string = [NSMutableString stringWithString:@"Mac"]; // 範囲を指定して、文字列を削除する [string deleteCharacterInRange:NSMakeRange(0,1)]; NSLog(string); // 文字列は、"ac"になる |
■ 文字列の比較
等しいかどうかの比較
2つの文字列が同じ文字列かどうか調べるメソッド、isEqualToString:。
NSString
1 2 | - (BOOL) isEqualToString:(NSString*)string 文字列 string が、こも文字列と等しかったら YES 、違っていたら NO を返す |
使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 | NSString* stringA = @"Mac OS X"; NSString* stringB = @"Mac OS X"; NSString* stringC = @"Windows"; BOOL result; // 文字列を比較する result = [stringA isEqualToString:stringB]; // この結果は YES になる result = [stringA isEqualToString:stringC]; // この結果は NO になる |
前置子と後置子の比較
文字列がある特定の前置子や後置子を持っているか調べることもできる。つまり、ある文字で始まっているか、またはある文字で終わっているかどうかを調べる。hasPrefix: と hasSuffix を使う。
NSString
1 2 3 4 | - (BOOL)hasPrefix:(NSString*)string この文字列が、文字列 string で始まっているなら YES、そうでないなら NO を返します。 - (BOOL) hasSuffix:(NSString*)string この文字列が、文字列 string で終わっているなら YES、そうでないなら NO を返す。 |
使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 | NSString* stringA = @"Mac Pro"; NSString* stringB = @"MacBook"; BOOL result; // 前置子を調べる result = [stringA hasPrefix:@"Mac"]; result = [stringB hasPrefix:@"Mac"]; // 両方とも結果は YES になる // 後置子を調べる result = [stringA hasPrefix:@"Pro"]; result = [stringB hasPrefix:@"Pro"]; // 前者は YES 、後者は NO になる。 |
■ 文字列の検索
指定した文字列がある範囲を調べることができる。返り値は NSRange になる。検索に関するいろいろなオプションを指定できる。
NSString
1 2 3 4 | - (NSRange) rangeOfString:(NSString)subString - (NSRange) rangeOfString:(NSString)subString options:(insigned)mask - (NSRange) rangeOfString:(NSString)subString options:(unsigned)mask range:(NSRange)range この文字列の検索をして、文字列 subString がある範囲を返す。検索のためのオプションを mask として指定することや、検索の範囲を range で指定することができる。 |
検索の結果、見つかればその範囲が返ってくる。見つからなかった場合は、返り値の NSRange の location に NSNotFound という値が返ってくる。これを使って、見つかったかどうかのチェックをする。検索のオプションは以下。
| オプション | 説明 |
|---|---|
| NSCaseInsensitiveSerch | アルファベットの大文字小文字を無視する |
| NSLiteralSerch | 文字列をバイトごとに検索する |
| NSBackwardSerch | 範囲の終わりから検索する |
| NSAnchoredSerch | 指定した範囲の先頭だけを検索する。文字列の途中に検索文字が出てきても無視する。 |
使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | NSString* string = @"This is Mac OS X"; // 文字列を検索する NSRange range; range = [string rangeOfString:"Mac OS X"]; // 見つかった場合 if (range.location != NSNotFound) { NSLog(@"Found at Location=%d, length=%d", range.location, range.length); } // 見つからなかった場合 else { NSLog(@"Not found"); } |
■ 文字列の一部を抜き出す
サブストリングの取得と呼ばれるもの。抜き出し方は3通りある。先頭から指定したインデックスまで、指定したインデックスから最後まで、範囲を指定するもの、この3つ。
NSString
1 2 3 4 5 6 | - (NSString*) substringToIndex:(unsigned)index この文字列の、先頭からインデックス index までの文字列を返す。 - (NSString*) substringFromIndex:(unsigned)index この文字列の、インデックスか index から最後までの文字列を返す。 - (NSString*) substringWithIndex:(unsigned)index この文字列の、範囲 range に含まれる文字列を返す。 |
使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | NSString* string = @"Happy Cocoa Programing"; // 先頭から文字列を取り出す NSString* stringA; stringA = [string substringToIndex:5]; NSLog(stringA); // stringA は、"Happy"となる // 最後までの文字列を取り出す NSString* stringB; stringB = [string substringFromIndex:12]; NSLog(stringB); // stringB は、"Prigraming"となる // 範囲を指定して文字列を取り出す NSString* stringC; stringC = [string substringWithRange:NSMakeRange(6,5)]; NSLog(stringC); // stringC は、"Cocoa"となる |
テキストファイルの読み込みと書き出し
■ テキストファイルの読み込み
テキストファイルを読み込む時は、そのエンコーディングも同時に指定することになる。
NSString
1 2 3 4 5 6 7 | + (id) stringWithContentsOfFile:(NSString*)path encoding:(NSStringEncoding)encoding error:(NSError**)error - (id) initWithContentsOfFile:(NSString*)path encoding:(NSStringEncoding)encoding error:(NSError**)error テキストファイルのパス path とエンコーディング encoding を指定して、ファイルを読み込む。読み込みに失敗した場合、エラー error が返る。 |
使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // テキストファイルを読み込む // path には適切なパスを指定する NSString* text; NSString* path = @"/Users/local/test.txt"; NSError* error; text = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error]; if (text) { // 読み込みが成功した場合 } else { // 読み込みが失敗した場合 NSLog([error localizedDescription]); } |
■ テキストファイルへの書き出し
指定したエンコーディングに変換されたテキストが、ファイルに保存されることになる。
NSString
1 2 3 4 5 | - (BOOL) writeToFile:(NSString*)path atomically:(BOOL)useAuxiliaryFile encoding:(NSStringEncoding)encoding error:(NSError**)error; パス path とエンコーディング encoding を指定して、テキストをファイルに書き出す。補助ファイルを使うかどうか、useAuxiliaryFile で指定する。書き出しに失敗した場合、エラー error が返る。 |
読み込みの時と同様、パスとエンコーディングを指定する。useAuxiliary は YES にしておく。使用例は以下。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // テキストファイルへ書き出す // path には適切なパスを指定する NSString* text = @"Cocoa programming"; NSString* path = @"/Users/local/test.txt"; NSError* error; BOOL result; result = [text writeToFile:path atomically:YES encoding:NSUTF8StringEncodng error:&error]; if (result) { // 書き出しが成功した場合 } else { // 書き出しが失敗した場合 NSLog([error localizedDescription]); } |