Objective-C 文字列操作,結合,切り出し 【初級編 第18回】


Objective-C 文字列操作,結合,切り出し 【初級編 第18回】

文字列の操作

前回前々回はObjective-Cでの文字列の作成に関してでしたが、今回はその文字列を操作する方法について説明します。
NSStingクラスには文字列を結合したり、切り出したりするためのメソッドが用意されています。
ここではその中の一部メソッドである「文字列長取得」「結合」「切り出し」「比較」に関して紹介します。

文字列長取得

文字列の長さを取得する際に使用できるメソッドとして以下のものがあります。
– (NSUInteger) length;

このメソッドを使用することで現在NSStringオブジェクト内に格納されている文字の長さを調べることができます。
今までのサンプルでは特に使いどころがありませんが試しに「main.m」に付け加えて動作を見てみます。
main.m

#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import "Bmi.h"
#import "Person.h"
#import "Manage.h"

int main(void){
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *name = [[NSString alloc] initWithString:@"Yamada"];
    //NSString *name = [NSString stringWithString:@"Yamada"];
    //NSString *name = @"Yamada";
    Person *teacher = [[Person alloc] initWithWeight:56.0 height:1.72 name:name];
    printf("Teacher Name:%sn",[[teacher name] UTF8String]);
    printf("Length:%dn",[[teacher name] length]);
    Manage *manage = [[Manage alloc] init];
    [manage setPerson:teacher];
    [teacher release];
    [manage showBestPerson];
    [manage release];
    [pool drain];

    [name release];
    return 0;
}

9行目、10行目、11行目のところに前回扱っていた文字列生成方法を3つ書いています。
14行目で文字数を取得してそれを表示させる処理を書いています。このメソッドで取得できる文字数というのは
バイト数ではなく、文字の数です。

結果は次のようになります。
Objc-130110_1
「Length」と表示されている部分が長さを表しています。「Y」「a」「m」「a」「d」「a」の6文字なので「6」と出ています。

結合

結合に使用できるメソッドとして以下のものがあります。
– (NSString*) stringByAppendingString: (NSString*)aString;
– (NSString*) stringByAppendingFormat: (NSString*)format,…;

「stringByAppendingString」メソッドは元の文字列に文字列を追加して新しく文字列を作成するという動作をします。
戻り値として新しい文字列が戻ってきますが、解放処理をする必要はありません。
前回の参考のところでAUTORELEASEというマクロを紹介しましたが、
このメソッドも実装を見てみると値を返すときにAUTORELEASEマクロを使用していました。

「stringByAppendingFormat」メソッドは元の文字列に文字列だけでなく変数の値なども追加して新しく文字列を作成すると
いう動作をします。
引数「format」のところに書式を指定した文字列をいれます。後ろに「….」となっているのは、引数が1つ以上という意味に
なります。1つ指定することもあれば、3つ指定することも可能となります。
例えばformatのところに「( )の天気は( )です」というような文字列を指定して、引数を2つ用意して
「今日」「晴れ」と指定すると「今日の天気は晴れです」という文字列になります。
( )の部分は格納したい変数の型により変わります。以下に一例をあげておきます。

種別 書式
文字列 %@
符号なし10進数 %d
小数 %e

このメソッドは内部で「stringByAppendingString」メソッドを呼び出しているので、戻り値として
返ってきた文字列に対して「release」を呼ぶ必要がありません。

では実際に使用してみます。

#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import "Bmi.h"
#import "Person.h"
#import "Manage.h"

int main(void){
    int age = 20;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *name = [[NSString alloc] initWithString:@"Yamada"];
    NSString *fname = [[NSString alloc] initWithString:@"Tarou"];
    //NSString *name = [NSString stringWithString:@"Yamada"];
    //NSString *name = @"Yamada";
    Person *teacher = [[Person alloc] initWithWeight:56.0 height:1.72
                name:[name stringByAppendingString:fname]];
    printf("Teacher Name:%sn",[[teacher name] UTF8String]);
    Manage *manage = [[Manage alloc] init];
    [manage setPerson:teacher];
    [teacher release];
    [manage showBestPerson];
    [manage release];

    NSString *info = [@"My name is" stringByAppendingFormat:@" %@ %@.I am %d years old.",name,fname,age];
    printf("%sn",[info UTF8String]);

    [pool drain];
    [name release];
    [fname release];
    return 0;
}

11行目で結合用の文字列を作成しています。
14行目と15行目でnameとlnameを結合して新たにできた文字列を引数としてPersonクラスをインスタンス化しています。
ここは単純な文字列結合となっています。
23行目のところで「stringByAppendingFormat」メソッドを使用して文字列を結合しています。
以前述べたように@”文字列”はオブジェクトとして扱われるので「My name is」というオブジェクト定数に対して
「stringByAppendingFormat」メッセージを送信しています。
フォーマットの指定としては「%@ %@.I am %d years old.」の「%@ %@」の部分には引数の「name」「fname」が
順番に結合されていきます。「%d」のところは8行目で定義したint型のageの内容が入ります。

実行結果を見てみましょう。
Objc-130110_2
結合されていますね。

検索

検索に使用できるメソッドとして以下のものがあります。
– (NSRange) rangeOfString: (NSString*)string;

レシーバーとなる文字列の中から引数で指定した文字列の位置と長さをNSRange構造体で返します。
構造体というのは関連するデータを1まとめにしたものです。「構造体名.メンバ」と指定することで内容に
アクセスできます。
NSRangeには位置を表す「location」と長さを表す「range」があります。

切り出し

切り出しに使用できるメソッドとして以下のものがあります。
– (NSString*) substringFromIndex: (NSUInteger)index;
– (NSString*) substringToIndex: (NSUInteger)index;

「substringFromIndex」は引数で指定された位置から末尾までの文字列を新しい文字列として作成します。
このときindex位置は新しい文字列に含まれます。
「substringToIndex」は先頭から引数で指定された位置までの文字列を新しい文字列として作成します。
このときindex位置は新しい文字列に含まれません。
どちらのメソッドもメソッド側でAUTORELEASEマクロが使用されているので「release」をする必要は
ありません。

実際に使用してみます。検索と同時に使用してみます。

#import <Foundation/Foundation.h>
#import <Foundation/NSObject.h>
#import "Bmi.h"
#import "Person.h"
#import "Manage.h"

int main(void){
    int age = 20;
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    NSString *name = [[NSString alloc] initWithString:@"Yamada"];
    NSString *fname = [[NSString alloc] initWithString:@"Tarou"];
    //NSString *name = [NSString stringWithString:@"Yamada"];
    //NSString *name = @"Yamada";
    Person *teacher = [[Person alloc] initWithWeight:56.0 height:1.72 name:[name stringByAppendingString:fname]];
    printf("Teacher Name:%sn",[[teacher name] UTF8String]);
    Manage *manage = [[Manage alloc] init];
    [manage setPerson:teacher];
    [teacher release];
    [manage showBestPerson];
    [manage release];
  
    NSString *info = [@"My name is" stringByAppendingFormat:@" %@ %@.I am %d years old.",name,fname,age];
    printf("%sn",[info UTF8String]);
    NSRange range = [info rangeOfString:@"."];
    printf("%sn",[[info substringToIndex:range.location+1] UTF8String]);
    printf("%sn",[[info substringFromIndex:range.location+1] UTF8String]);
    [pool drain];
    [name release];
    [lname release];
    return 0;
}

今までのコードに関係内処理ですが24行目から26行目が先ほどから増えた部分となります。
「.」の位置を探し、それより前の文字列と後ろの文字列に分けようと思います。
24行目では「My name is Yamada Tarou.I am 20 years old.」から「.」の位置を検索して構造体に格納しています。
25行目で取得した位置までの文字列を表示しています。このとき位置が含まれないので+1しています。
26行目では取得した位置から後ろの文字を表示しています。このとき位置を含むので(「.」が頭にきてしまう)ので
これも+1しています。

結果は以下のようになります。
Objc-130110_3

比較

文字列の比較に使えるメソッドとして以下のものがあります。
– (BOOL) isEqualToString: (NSString*)aString;

引数に比較したい文字列を指定します。
戻り値は同一文字列であれば「YES」が異なっている場合「NO」が返されます。

今回紹介したメソッドはNSStringのメソッドの一部ですので、他のものを確認したい場合は、
リファレンスを参照してください。

まとめ

今回のまとめとしては

  • NSStringには「文字列長取得」「結合」「切り出し」「比較」といったメソッドが用意されている
  • それらのメソッドを使用することで新しい文字列が作成されるが解放処理は不要な場合がある

といったところでしょうか。

  • このエントリーをはてなブックマークに追加

PAGE TOP