2011-07-27 11 views
0

私はこのコードを改行で区切られたテキストファイルで読み込みます。私がしたいことは、すべての単語を配列に読み込んだ後、その配列から6文字の単語すべてを選択することです。配列から特定の長さの文字列を取る

私はこのコードを以下に示しますが、forループ内からエラーが発生しているようです。

また、テキストファイルを読み込んだ後、リリースする必要がありますか?

NSString* path = [[NSBundle mainBundle] pathForResource:@"newdict" ofType:@"txt"]; 

NSString* content = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL]; 

NSArray* allLinedStrings = [content componentsSeparatedByCharactersInSet: 
[NSCharacterSet newlineCharacterSet]]; 

int wordcount = [allLinedStrings count]; 
int i; 
NSMutableArray* sixLetterWords; 

for(i = 0 ; i < wordcount ; i++) 
{ 
    NSString* word = [allLinedStrings objectAtIndex: i]; 
    if (StrLength(word) == 6) 
     [sixLetterWords addObject:word]; 
} 
+1

将来の質問では、表示されているエラーとは何かを推測させるのではなく、特定のエラーメッセージを表示することをお勧めします。 – smorgan

+0

次回はこの点を心に留めておきます:) – kazuo

答えて

3

より良いオプションfast enumerationです:

enumerateObjectsUsingBlock:
// Don't forget to actually create the mutable array 
NSMutableArray * sixLetterWords = [[NSMutableArray alloc] init]; 
for(NSString * word in allLinedStrings){ 
    if([word length] == 6) [sixLetterWords addObject:word]; 
}  

blocks-based enumeration

NSMutableArray * sixLetterWords = [[NSMutableArray alloc] init]; 
[allLinedStrings enumerateObjectsUsingBlock:^(id word, NSUInteger idx, BOOL * stop){ 
    if([(NSString *)word length] == 6) [sixLetterWords addObject:word]; 
}]; 

filter the arrayへの可能性もあります:

NSArray * sixLetterWords = [allLinedStrings filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"length == 6" 

(注)このこと最後のオプションはヨーヨーを与えるオートレリースされた配列 - あなたがそれを保持したいなら、それを保持しなければなりません。これらのいずれを使用しても、配列の長さや明示的な索引付けを心配する必要はありません。それは配列によってあなたのために処理されます。 Fast enumerationも、その名前が示すように、速いループよりも、forループです。

、あなたの文字列にテキストファイルを読み取るために使用される方法、stringWithContentsOfFile:encoding:error:は、newallocではない、またそれはcopyまたはmutableCopyで始まるん。したがって、Cocoa memory management rulesによれば、あなたはそれを所有しておらず、それを解放する必要はありません。 (あなたはそれが現在のメソッドの終わりを過ぎて周りに固執したいなら、あなたはそれを維持する必要があります。)

+0

AWESOME!この回答をありがとうございます! – kazuo

1

テキストファイルは自動リリースされるため、リリースする必要はありません。

EDIT:

あなたがALLOCする必要があるとNSMutableArrayのあなたを初期化

...

NSMutableArray* sixLetterWords = [[NSMutableArray alloc] init]; 

私はあなたが右の初めてそれを持っていた、のためのループビットが間違っていました。 forループより

+0

これを試してみましたが、コンパイルエラーはありませんが、特に '[sixLetterWords addObject:word];行"スレッド1:プログラム受信信号:EXC_BAD_ACCESS"。 – kazuo

+0

編集内容を読む... –

+0

この回答の最初の部分は間違っています。 i smorgan

0

私自身のトランペットを吹くは望まないが、CMFunctionalAdditionsフレームワークは、よりきれいにすると同時に、これを行うことができます:)

NSArray* sixLetterWords = [allLinedStrings filterWithPredicate:^BOOL(NSString* str) { 
    return [str length] == 6; 
}]; 
+0

あなたの作品を共有してくれてありがとう!あなたは本当にあなたのカテゴリメソッド名にプレフィックスを付けるべきです。また、このメソッドの名前は組み込みの['filteredArrayUsingPredicate:'](http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html#)に非常に似ています// apple_ref/doc/uid/20000137-BAJJDBEB)、これはブロックではなく 'NSPredicate'オブジェクトをとります。 –

+0

大規模なコレクションや最も複雑な述語を除き、filderedArrayUsingPredicateは最も簡単なソリューションです。アップルがこれを同時に稼働させるまでには時間の問題だと思う。 –

+0

私は実装についてではなく、名前について話していました。カテゴリをフレームワーククラスに追加するときは、アップルがあなたの名前と同じ名前のメソッドを決して追加しないようにする必要があります。これを行う従来の方法は接頭辞 'CM_filteredArrayUsingPredicate:'を使用します。 –

関連する問題