NSString についての覚え書き

Last-modified: 2014-01-11 (土) 10:47:34

NSString

初期化

リテラル記法で作成

NSString *aString1 = @"\n\tはじめまして!\n\tHello, OBjective-C!";

空白文字で連結

NSString *aString2 =
	@"家から出発し、"
	@"バスに乗って、"
	@"会社に着いた" "。";

書式に従った、文字列の初期化

NSString *str_ns_1 = [NSString stringWithFormat:@"%@, %@, %@",
			@"あけまして",
			@"おめでとう",
			@"ございます。"];

Cの文字列から生成

const char *cString = "ABCDE、美しい日本語。";
NSString *aString3 = @(cString);
NSString *aString4 = [NSString stringWithUTF8String:cString];
NSLog(@"C文字列から生成:ボクシング記法 %@", aString3);
NSLog(@"C文字列から生成:メソッド使って %@", aString4);

unichar 部分文字列から、NSString 文字列の作成

const unichar uniStr2[] = {L'零', L'壱', L'弐', L'参', L'四', L'五', L'六', L'七', L'八', L'九'};
NSString *str3
= [NSString stringWithCharacters:(const unichar *)uniStr2 length:(NSUInteger)5 ];
NSLog(@"unichar to partially NSString: %@", str3);

メソッドを使って作成

... not written ...

文字列の操作

結合と分離

NSString *str1 = @"あかさたな";
NSString *str2 = @"はまやらわ";
//末尾へ追加
NSString *str3 = [str1 stringByAppendingString:str2];
NSLog(@"%@", str3);
NSString *str4 = [str1 stringByAppendingFormat: @" => %@ => %@", str2, @"をん"];
NSLog(@"%@", str4);

部分文字列を取り出して、文字列として返す

NSString *str = @"零壱弐参四五六七八九";
NSLog(@"anIndex が示す位置までの文字列:  %@", [str substringToIndex: 3]);
NSLog(@"anIndex が示す位置から末尾まで:  %@", [str substringFromIndex: 3]);
//NSRange で、範囲指定
NSRange aRange = {2,4};
NSLog(@"aRange で示される範囲の文字列:  %@", [str substringWithRange: aRange]);

unicharからNSStringへの変換

const unichar uniStr1[] = {L'テ', L'ス', L'ト'};
NSString *str1 = [NSString stringWithFormat:@"%S%S%S", uniStr1, uniStr1, uniStr1 ];
NSLog(@"unichar to NSString: %@", str1);

部分文字列をunichar へ取得。

NSRange aRange = NSMakeRange(2, 4);
const unichar buffer[100]; // constを付けないとダメ
[@"零壱2参④5⑥七⑧9" getCharacters:(unichar *)buffer range:aRange];
NSLog(@"%S", buffer);
// 指定子 %S => NULL終端の16ビットUnicode文字配列。
//たしかに内部でUTF8は二バイト表現。

UTF-8 との相互互換

const char *cStr = "こんにちわ";
printf("Original C-string: %s\n", cStr);
NSString *str1 = [NSString stringWithUTF8String: cStr];
NSLog(@"NSString from C-string: %@", str1);
const char *cStr2 = [str1 UTF8String];
printf("C-string from NSString: %s\n", cStr2 );
NSUInteger strLength = [str1 length];
NSLog(@"length of string: %lu", strLength );
for (int i = 0; i < [str1 length] ; i ++) {
	unichar character = [str1 characterAtIndex:i ];
	NSLog(@"uni_c(%%C) = %C", character);
	NSLog(@"uni_c(%%X) = %X\n", character);
}
NSLog(@"\\u3053 = \u3053");`		// 「テ」と表示される。
NSLog(@"0x3053 = %C", (unichar)0x3053);	// 「テ」と表示される。

大文字と小文字の取り扱い

NSString *aStr = @"tHe uniVeRSity oF toKYo";
NSLog(@"lower case: %@", [aStr lowercaseString]);
NSLog(@"upper case: %@", [aStr uppercaseString]);
NSLog(@"capitalized:%@", [aStr capitalizedString]);

数値として取り扱い

NSString *aStr1 = @"123";
NSLog(@"Original val: %@", aStr1);
NSLog(@"double value: %f", [aStr1 doubleValue]);
NSLog(@"float  value: %f", [aStr1 floatValue]);
NSLog(@"int    value: %d", [aStr1 intValue]);
NSLog(@"NSInteger val:%ld", (long)[aStr1 integerValue]);

パスを表す文字としての取り扱い

NSString *aStr1 = @"/Users/john/Documents/hoge/foo.txt";
NSLog(@"末尾の要素: %@", [aStr1 lastPathComponent]);
NSLog(@"末尾に文字追加     : %@", [aStr1 stringByAppendingString:@"/component"]);
NSLog(@"末尾の構成要素を削除: %@", [aStr1 stringByDeletingLastPathComponent]);
NSLog(@"拡張子を返す: %@", [aStr1 pathExtension]); // .は含まれない、拡張子がないと空文字
NSLog(@"ドットと、指定文字列: %@", [aStr1 stringByAppendingPathExtension: @"zip"]);
NSLog(@"ドットと、拡張子削除: %@", [aStr1 stringByDeletingPathExtension]);
NSLog(@"絶対パスですか?: %@", [aStr1 isAbsolutePath] ? @"Yes!" : @"No.");
NSLog(@"配列を連結してパス文字列: %@",
	[NSString pathWithComponents:
 		@[
 			@"/",
 			@"local",
 			@"usr",
			@"bin",
			@"perl",
		]
	]
);
NSLog(@"パス文字列を分解して配列: %@", [aStr1 pathComponents]);
NSLog(@"チルダを展開: %@", [@"~/Document" stringByExpandingTildeInPath]);
NSLog(@"チルダを使う e: %@", [aStr1 stringByAbbreviatingWithTildeInPath]);
// ToDo: 動かないよ
const char *systemPath = [aStr1 fileSystemRepresentation];
// systemPath にはちゃんと文字列が入っている。
NSLog(@"file system represent: %C", systemPath);
// 何も表さない。指定子が間違っているのか?

文字列の比較

文字列の一致 isEqualToString: メソッド

NSLog(@"equality? %@",
	[str isEqualToString:str2]
	? @"Yes!"
	: @"No."
	);

文字列の比較 compare: メソッド

NSString *str = @"あいうえお";
NSString *str2 = @"あいうえを";
NSString *str3 = @"あいうええ";
NSString *str4 = @"あいうえお";
NSComparisonResult cmpStr = [NSNotFound];
cmpStr = [str compare: str2];
NSLog(@"%@ compare with %@ => %ld", str, str2, cmpStr);
cmpStr = [str compare: str3];
NSLog(@"%@ compare with %@ => %ld", str, str3, cmpStr);
cmpStr = [str compare: str4];
NSLog(@"%@ compare with %@ => %ld", str, str4, cmpStr);

文字列の比較、大文字小文字関係なく caseInsetntiveCompare:

NSString *aStr = @"abcdefg";
NSString *aStr1 = [@"abcde" stringByAppendingString:@"FG"];
NSString *aStr2 = [NSString stringWithFormat:@"%@%@", @"ABC", @"DEFG"];
NSLog(@"case insentive compare (NSComparisonResult):  %@ vs %@ => %ld",
	aStr,
	aStr1,
	[aStr caseInsensitiveCompare:aStr1]
	);
NSLog(@"case insentive compare (NSComparisonResult):  %@ vs %@ => %ld",
	aStr,
	aStr2,
	[aStr caseInsensitiveCompare:aStr2]
	);

接頭語、接尾語一致 hasPrefix, hasSuffix

NSString *aStr3 = @"abcd";
NSLog(@"hasPrefix: %@ vs %@ => %@",
	aStr,
	aStr3,
	([aStr hasPrefix:aStr3] ? @"YES" : @"NO")
);
NSString *aStr4 = @"efg";
NSLog(@"hasPrefix: %@ vs %@ => %@",
	aStr,
	aStr4,
	([aStr hasSuffix:aStr4] ? @"YES" : @"NO"));

検索と置換

引数の文字列の位置と長さを取得

NSString *aStr = @"零壱弐参四五六七八九";
NSRange aRange = {0, 0};
aRange= [aStr rangeOfString:@"四五六"];
NSLog(@"指定した文字列のレンジは、位置 %lu、 長さ %lu",
	aRange.location,
	aRange.length);
aRange= [aStr rangeOfString:@"四⑤六"];
NSLog(@"指定した文字列のレンジは、位置 %lu、 長さ %lu",
/  文字列が見つからないと 返り値の NSRange は不定。
// NSNotFound型と比較しなくてはならない。

aRange で指定した範囲を、引数文字列で置換

NSString *aStr = @"零壱弐参四五六七八九";
NSRange aRange2 = {3, 2};
NSLog(@"aRange で指定した範囲を、引数文字列で置換:  %@",
	[aStr stringByReplacingCharactersInRange:aRange2 withString:@"34"]);

引数の文字列で置換できる回数を返す

NSString *str1 = @"kjoakjliwljidljakjleaaljelda";
NSString *aTarget = @"a";
NSString *aReplacement = @"_A_";
NSLog(@"全ての target をreplacement で置き換えた文字列: %@ replaced with %@ => %@",
	str1,
	aTarget,
	[str1 stringByReplacingOccurrencesOfString:aTarget withString:aReplacement]
	);

正規表現をもちいた検索

NSString *str2 = @"東京都 123-4567 千代田区";
NSRange aRangeExp
	= [str2 rangeOfString:@"[0-9]{3}+-[0-9]{4}+" options:NSRegularExpressionSearch];
NSLog(@"正規表現で、文字列の検索:  location => %lu, length = %lu in %@",
	aRangeExp.location,
	aRangeExp.length,
	str2);

ファイル入出力

ファイルから文字列を読み込む

 改行も飲み込む。

NSError *error;
NSString *aContentOfFile =
	[NSString stringWithContentsOfFile:@"/Users/john/hoge.txt"
		encoding:NSUTF8StringEncoding
		error:&error];
if (aContentOfFile != nil) {
	NSLog(@"content of file:\n%@", aContentOfFile);
	// その他。キャラクターで切り分ける
	NSLog(@"separate with charSet: %@",
		[aContentOfFile
			componentsSeparatedByCharactersInSet:
			[NSCharacterSet newlineCharacterSet]]);
} else {
	NSLog(@"error occured!  \n%@", error);
}

文字エンコードを自動判別

 aEncに文字列タイプを指定。

NSError *error;
NSStringEncoding aEnc = 0;
NSString *aContentOfFile2 =
	[NSString
		stringWithContentsOfFile:@"/Users/john/hoge.txt"
		usedEncoding:&aEnc
		error:&error];
if (aContentOfFile2 != nil) {
	NSLog(@"content of file:\n%@", aContentOfFile2);
} else {
	NSLog(@"error occared!  \n%@", error);
}
if (aEnc) {
	NSLog(@"encoding type: %ld", aEnc);
}

文字列をファイルへ書込

 ファイルが存在してても上書き。

NSError *error;
NSString *pathToFile = @"/Users/john/foo/bar.txt";
BOOL aUseAuxiliaryFile = YES; // atomic な書込。通常 YES
NSStringEncoding aEnc2 = NSUTF8StringEncoding;
BOOL isSuccess = [@"なんでも書き込めました\n改行も出来ます。"
	writeToFile:pathToFile
	atomically:aUseAuxiliaryFile
	encoding:aEnc2
	error:&error];
NSLog(@"%@", isSuccess ? @"書込成功!" : @"書込失敗");

NSMutableString

 可変長の文字列オブジェクト。メソッドで、自分自身を操作する。

初期化

NSMutableString *aStr1 = [[NSMutableString alloc] init];
NSMutableString *aStr2 = [[NSMutableString alloc] initWithCapacity:100];

追加

[aStr1 appendString:@"初めまして、Mac です。"];
[aStr2 appendFormat:@"私の名前は、%@ (%d).", @"Mac Book Pro", 2010];

挿入

[aStr1 insertString:@"intosh" atIndex:9];
NSLog(@"aStr1 inserted: %@", aStr1);

削除

NSRange aRange; aRange.location = 1; aRange.length = 3;
[aStr2 deleteCharactersInRange:aRange];

上書き(総入れ替え)

[aStr2 setString:@"Hello!World."];

操作

NSRange の範囲を置換

NSRange aRange2 = {0, 5};
[aStr2 replaceCharactersInRange:aRange2 withString:@"Howdy"];
       NSLog(@"aStr2 replaced: %@", aStr2);

置換文字列を指定して置換

NSMutableString *aStr3 = [[NSMutableString alloc] initWithString:@"aadefalnoPu"];
NSString *aTarget = @"a";
NSString *aReplacement = @"_A_";
NSStringCompareOptions aOpts = NSCaseInsensitiveSearch;
NSRange aRange3; aRange3.location = 0; aRange3.length = [aStr1 length];
NSUInteger count = 0;
count = [aStr3 replaceOccurrencesOfString:aTarget
	withString:aReplacement
	options:aOpts
	range:aRange3];
NSLog(@"\nreplaced target(%@) to replacement(%@),\n resulting '%@',\n %lu times.",
	aTarget,
	aReplacement,
	aStr3,
	(unsigned long)count
	);

その他

定数の文字列リテラルは、同じインスタンスを利用する

NSString *str1 = @"abcde";
NSString *str2 = @"ABCDE";
NSString *str3 = @"ABCDE";
NSString *str4 = [@"ABC" stringByAppendingString:@"DE"];
for (NSString *str in @[str1, str2, str3, str4]) {
		NSLog(@"String %@'s address is\t%p", str, str);
}

メソッド呼び出しと、ドット演算子の呼び出し

// メソッド呼び出し
NSUInteger length1 = [@"ABCDE" length];
NSLog(@"method: %lu", (unsigned long)length1);
// ドット演算子
NSUInteger length2 = @"あいうえを".length;
NSLog(@"dot operator: %lu", (unsigned long)length2);

NSStringで使える書式指定子

指定子解説
%@Objective-Cオブジェクト。利用可能ならdescriptionWithLocale:ないしdescriptionが返す文字列を表示する。同様にCFTypeRefオブジェクトも対象で、CFCopyDescriptionの結果を返す。
%%'%'文字
%d, %D, %i符号付き32ビット整数(int)
%u, %U符号なし32ビット整数(unsigned int)
%hi符号付き16ビット整数(short)
%hu符号なし16ビット整数(unsigned short)
%qi符号付き64ビット整数(long long)
%qu符号なし64ビット整数(unsigned long long)
%x符号なし32ビット整数(unsigned int)を16進表記。小文字のa~fを用いる。
%X符号なし32ビット整数(unsigned int)を16進表記。大文字のA~Fを用いる。
%qx符号なし64ビット整数(unsigned int)を16進表記。小文字のa~fを用いる。
%qX符号なし64ビット整数(unsigned int)を16進表記。大文字のA~Fを用いる。
%o, %O符号なし32ビット整数(unsigned int)を8進表記。
%f64ビット浮動小数点値(double)
%e64ビット浮動小数点値(double)を指数表記。指数文字は小文字のeを用いる。
%E64ビット浮動小数点値(double)を指数表記。指数文字は大文字のEを用いる。
%g64ビット浮動小数点値(double)を指数が-4~5なら%e形式で、それ以外は%f形式で表示する。
%G64ビット浮動小数点値(double)を指数が-4~5なら%E形式で、それ以外は%f形式で表示する。
%c8ビット符号なし文字(unsigned char)。NSLog()ではASCIIキャラクターを表示し、非ASCIIキャラクターの場合は\\dddの8進表記で、Unicodeは\\uddddの16進表記で表示する(ここでdは桁を表す)。
%C16ビットUnicode文字(unichar)。NSLog()ではASCIIキャラクターを表示し、非ASCIIキャラクターの場合は\\dddの8進表記で、Unicodeは\\uddddの16進表記で表示する(ここでdは桁を表す)。
%sNULL終端の8ビット符号なし文字配列。%s interprets its input in the system encoding rather than, for example, UTF-8.
%SNULL終端の16ビットUnicode文字配列。
%pvoidポインタ(void *)。0xに続く16進表記。小文字のa~fを用いる。
%L長さ修飾子。a, A, e, E, f, F, g, Gを前置修飾し、long doubleの引数を受ける指定子へと変化させる。
%a64ビット浮動小数点値(double)を16進の科学的記数法で表示する。小数点の前に0xで始まる1桁の16進数を持ち、指数は小文字のpの後ろに記す。
%A64ビット浮動小数点値(double)を16進の科学的記数法で表示する。小数点の前に0Xで始まる1桁の16進数を持ち、指数は大文字のPの後ろに記す。
%F64ビット浮動小数点値(double)を10進表記法で表示する。
%z長さ修飾子。d, i, o, u, x, Xを前置修飾し、size_tないし相当する符号付き整数型の引数を取る指定子へと変化させる。
%t長さ修飾子。d, i, o, u, x, Xを前置修飾し、ptrdiff_tないし相当する符号付き整数型の引数を取る指定子へと変化させる。

|%j|長さ修飾子。d, i, o, u, x, Xを前置修飾し、intmax_tまたはuintmax_tの引数を取る指定子へと変化させる。