外部のCSVファイルを読み込み解析する方法

このQ&Aのポイント
  • objectiv-cで外部のCSVファイルを読み込んで解析する方法について教えてください。
  • CSVファイルの中身は文章と数字がカンマで区切られています。
  • 既に外部のテキストファイルを読み込む方法を学習済みですが、CSVファイルの読み込みについての情報が不足しています。
回答を見る
  • ベストアンサー

objectiv-cで困っています。教えてください

以前に外部のテキストファイルの中身を読み込む質問をして解答をいただき、助かりました。今回はそれを参考に外部にあるCSVファイルを読み込み解析しようとしているのですが、うまくいきません。CSVの中身は文章,数字/文章,数字/文章,数字/…となっています。いろいろ調べてみたのですが、外部のCSVファイルの読み込みについて書かれているものが分かりませんでした。どのようにしたらよいのでしょうか、教えてください。 #import "ViewController.h" @interface ViewController () @end @implementation ViewController{ NSString* text; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. [self loadcsv]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //CSVの読み込み - (void)loadcsv { // CSVファイルの読み込み // 送信するリクエストを生成する。 NSURL *url = [NSURL URLWithString:@"http://....................../test.csv"]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; // リクエストを送信する。 // 第3引数のブロックに実行結果が渡される。 [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) { if (error) { // エラー処理を行う。 if (error.code == -1003) { NSLog(@"not found hostname. targetURL=%@", url); } else if (-1019) { NSLog(@"auth error. reason=%@", error); } else { NSLog(@"unknown error occurred. reason = %@", error); } } else { int httpStatusCode = ((NSHTTPURLResponse *)response).statusCode; if (httpStatusCode == 404) { NSLog(@"404 NOT FOUND ERROR. targetURL=%@", url); // } else if (・・・) { // 他にも処理したいHTTPステータスがあれば書く。 } else { text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; } } }]; // 行ごとに分割し、配列「lines」に格納 NSArray* lines = [text componentsSeparatedByString:@"\n"]; // 問題の数だけ繰り返し for(int i=0; i<[lines count]; i++){ //問題をカンマで区切って、要素を配列「items」に格納 NSArray* items = [[lines objectAtIndex:i] componentsSeparatedByString:@","]; NSString *q = [items objectAtIndex:0]; int a = [[items objectAtIndex:1] intValue]; // 変数の中身を出力する NSLog(@"文字列は%@", q); NSLog(@"数字は%d", a); }

  • dkong
  • お礼率86% (170/197)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

「うまくいかない」というのが、具体的にどのような動作になったり どのようなメッセージが出たりするのか、現象をちゃんと書かないと 普通はわかりません。 ただ、今回示されたコードは明らかな誤りがあるのでその点を指摘しておきます。 (もしかすると「うまくいかない」というのは、それ以前の問題で止まっているのかも しれませんが、具体的な現象を説明してないのでわかりません。) 今回示されたコードは、前回紹介した http://www.yoheim.net/blog.php?q=20130206 を参考に書いたものだと思いますが、 そこには ------------------------------- // ここはサブスレッドなので、メインスレッドで何かしたい場合には dispatch_async(dispatch_get_main_queue(), ^{ // ここに何か処理を書く。 }); ------------------------------- と書いてありますが、あなたのコードはそのようになってなく sendAsynchronousRequestのメソッド呼び出しが終わった後に処理が書かれてあります。 これじゃ動くわけありません。sendAsynchronousRequestの第3引数のブロック内に 読み込んだテキストの処理を書く必要があります。 おそらく、なぜこのようにしないといけないのかわからないのだと思います。 「ブロック構文」や「dispatch_async」のことを調べて勉強してください。

dkong
質問者

お礼

回答ありがとうございました。「ブロック構文」や「dispatch_async」のことが分かっていませんでした。アドバイスをいただいたように調べながら勉強してます。また、よろしくお願いします。

関連するQ&A

  • objective-cで困っています。

    objective-cをトライ&エラーで試しながら学習しているのですが、 下記の内容で行き詰っており、知恵をお借りしたいと思い投稿しました。 現在tml5のcanvasを使ってお絵描きアプリを作りました。このcanvasに書き込んだデータをiPhoneのカメラロールに保存することをトライしています。いろいろ調べてみると「HTML5 CANVASの描画内容をUIImage経由でカメラロールに保存する」という記事をみつけました。http://lab.spec5zigen.com/archives/html5-canvasの描画内容をuiimage経由でカメラロールに保存する/ その記事を参考に #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // UIWebViewのインスタンス化 CGRect rect = self.view.frame; UIWebView *webView = [[UIWebView alloc]initWithFrame:rect]; // Webページの大きさを自動的に画面にフィットさせる webView.scalesPageToFit = YES; // デリゲートを指定 webView.delegate = self; // URLを指定 NSURL *url = [NSURL URLWithString:@"http://xxxxxxxxxxxxxxxxxxxxxx"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; // リクエストを投げる [webView loadRequest:request]; // UIWebViewのインスタンスをビューに追加 [self.view addSubview:webView]; } - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { if(![[request.URL.scheme] isEqualToString:@"sp5canvas2app"]){ return YES; } NSString * requestString = [[request URL] absoluteString]; NSArray *params = [requestString componentsSeparatedByString:@"data:image/png;base64,"]; // dataFromBase64String // NSData+Base64 Copyright 2009 Matt Gallagher. All rights reserved. // http://www.cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html NSData * decodedData = [NSData dataFromBase64String:[params objectAtIndex:1]];//decode base64 to NSData UIImage *image = [UIImage imageWithData:decodedData]; UIImageWriteToSavedPhotosAlbum(image, self, nil, nil);//カメラロールに保存 return NO; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end としてみたのですが、 if(![[request.URL.scheme] isEqualToString:@"sp5canvas2app"]){ の行にExpected identifierというエラーが、 NSData * decodedData = [NSData dataFromBase64String:[params objectAtIndex:1]];の行にNo known class method for selector 'dataFromBase64String:'というエラーが という状況で詰っている状況です。 メソッドの定義や宣言されていないメソッドを使っているなどのエラーということを調べて分かったのですが、objective-cを始めたばかりで初歩的なミスかも知れませんがエラーの対応の仕方がまだまだよくわかっていません。 スキーマなど参考にしたサイトの内容も十分に理解しているのではないのですが、「sp5canvas2app」の部分は自由に変えていいのでしょうか? 解決の仕方を教えていただけないでしょうか? 宜しくお願いします。

  • objective-Cについてご相談があります。

    現在objective-cを勉強中なのですが、 jsonについて教えて頂きたい事があります。 jsonのファイル・データ・オブジェクトそれぞれを 取得する必要があると習ったのですが、それらの違いが 今ひとつ分かりません。 下記のような記述なのですが、それぞれの違いをどなたか ご教示頂けないでしょうか。 // 対象Jsonファイル取得 NSBundle *bnd = [NSBundle mainBundle]; NSString *ptn = [bnd pathForResource:@"Test01" ofType:@"json"]; NSURL *url = [NSURL fileURLWithPath:ptn]; // Jsonオブジェクトの取得 NSURLRequest *req =[NSURLRequest requestWithURL:url]; NSData *dat = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; // Jsonデータの取得 NSDictionary *dick01 = (NSDictionary *) [NSJSONSerialization JSONObjectWithData:dat options:NSJSONReadingMutableContainers error:nil]; 以上、何卒宜しくお願い致します。

  • 【iOS】pickerViewを隠すには?

    pickerViewを、画面のどこかをタップすることで隠すには どのようにすればよろしいでしょうか。 現在のコードです。 TextFieldの代わりにピッカーを出すという実装です。 ヘッダー @property(nonatomic,weak)IBOutlet UITextField *textField; @property(nonatomic,strong)UIPickerView *pickerView; @property(nonatomic,strong)NSArray *items; メイン - (void)viewDidLoad { self.items = @[@"A",@"B",@"C",@"D"]; self.pickerView = [[UIPickerView alloc]init]; self.pickerView.dataSource = self; self.pickerView.delegate = self; self.pickerView.showsSelectionIndicator = YES; self.textField.inputView = self.pickerView; [super viewDidLoad]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{ return 1; } - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{ return [self.items count]; } - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{ return [self.items objectAtIndex:row]; } - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{ self.textField.text = [self.items objectAtIndex:row]; } - (IBAction)pressHide:(id)sender{ [self.textField resignFirstResponder]; }

  • itunesStoreに画面遷移せず移動する方法

    tableView上の選択行から そのtableview内でitunesStoreを表示したいのですが、 やり方が分かりませんでした。。 また、画面遷移が行われた場合のitunesStoreの表示はできましたが その場合、ナビゲーションバーの色がデフォルトに戻ってしまい困っております。 以下のやり方を試しましたが、うまくビュー内に表示することができず ご教授いただければと思い質問させていただきました。 よろしくお願い致します。 *---------- .h @interface recVCL : UITableViewController <UIWebViewDelegate> { UIWebView *wv; } @end .m - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSString *compURL = @"http://phobos.apple.com/WebObjects/"; if(NSOrderedSame == [[[request URL] absoluteString] compare:compURL options:NSCaseInsensitiveSearch range:NSMakeRange(0,[compURL length])]) { [[UIApplication sharedApplication] openURL:[request URL]]; } return YES; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"xxxxxxx"; self.navigationController.navigationBar.tintColor = [[[UIColor alloc] initWithRed:(xxxxxxxxxx) green:(xxxxxxxxxxx) blue:xxxxxxxxxx) alpha:1.0f] autorelease]; wv = [[UIWebView alloc] initWithFrame:self.view.bounds]; [wv delegate]; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { NSURL *url; NSURLRequest *urlRq; switch (indexPath.row) { case 0: url = [NSURL URLWithString:@"http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=xxxxxxxxxxxx&mt=x"]; urlRq = [NSURLRequest requestWithURL:url]; [wv loadRequest:urlRq]; [self.view addSubview:wv]; break; ... }

  • Objective-c 画像処理

    Cについては、全くの素人です。 「Xcodeプログラミング大全」という書籍を参考に、開発を進めているのですが、行き詰まってしまったので、質問させて下さい。 ImageKitを使ったイメージブラウザを作成して、取り込んだ画像を別名で別の場所に保存するプログラムを作成しています。 前半部は文字数の関係で省略します。 ボタンをクリックして画像を保存します。 - (IBAction)myButton:(id)sender; { // imagebrowserに保存した画像を順番に処理 for(int i=0; i< [myImages count]; i++){ NSData *data = nil; NSString *errorDescription; //NSPasteboard *pasteboard = [myImages objectAtIndex:i]; if([[[myImages objectAtIndex:i] types] containsObject:NSFilenamesPboardType]) data = [[myImages objectAtIndex:i] dataForType:NSFilenamesPboardType]; if(data){ NSArray *filenames = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:kCFPropertyListImmutable format:nil errorDescription:&errorDescription]; for(int j=0;j< [filenames count];j++){ //NSLog(@"%@",[filenames objectAtIndex:j]); NSBitmapImageRep* bitmap = [myImages objectAtIndex:i]; // 画像保存 NSData* outdata = [bitmap representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]]; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES); NSString* path = [NSString stringWithFormat:@"%@/test.png",[paths objectAtIndex:0], nil]; [outdata writeToFile:path atomically:YES]; / } } } } @end エラーは発生しないのですが、コンソールに「[MyImageObject types]: unrecognized selector sent to instance 0xf722590」と表示されます。 また、画像は全く保存されません。 どなたか、ご教授をお願いします。

  • iphoneアプリの開発

    電卓アプリを作っています。 今困っているのは 1.割り算で小数点以下の計算ができない。 2.3つ以上の計算が(2×3×4のような)足し算しかできない。 3.間違えて数値を入力した場合に使うバックスペース的なボタンの作り方。 です。 どれか一つでもいいのでアドバイスいただけたらありがたいです。 #import "myViewController.h" @implementation myViewController // The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad. /* - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization. } return self; } */ // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. - (void)viewDidLoad { [super viewDidLoad]; startInput = YES; currentValue = 0; } -(IBAction)numberButtonPressed:(id)sender { UIButton *b = (UIButton *)sender; if( startInput ){ // 最初の1桁目が0なら表示しない if( b.tag == 0 ) return; // 新しく表示する文字列を作成 label.text = [NSString stringWithFormat:@"%d", b.tag]; startInput = NO; } else { // すでに表示されている文字列に連結 label.text = [NSString stringWithFormat:@"%@%d", label.text, b.tag]; } NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)equalButtonPressed:(id)sender { currentValue = sum; sum = sum-sum; // 直前に押された演算子で場合分け if( operation == 0 ){ currentValue += [label.text intValue]; } else if( operation == 1 ){ currentValue -= [label.text intValue]; } else if( operation ==2){ currentValue *= [label.text intValue]; } else if (operation ==3){ currentValue /= [label.text intValue]; } // 表示の更新 label.text = [NSString stringWithFormat:@"%d", currentValue]; startInput = YES; label2.text =@"="; NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)opButtonPressed:(id)sender { UIButton *b = (UIButton *)sender; // 現在値の保存 if( operation == 0 ){ currentValue= [label.text intValue]; sum +=currentValue; label.text =[NSString stringWithFormat:@"%d", sum]; } // 演算の保存 operation = b.tag; startInput = YES; if( operation == 0 ){ label2.text =@"+"; } if( operation == 1 ){ label2.text =@"-"; } if( operation == 2 ){ label2.text =@"×"; } if( operation == 3 ){ label2.text =@"÷"; } NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } -(IBAction)clearButtonPressed:(id)sender { label.text = @"0"; startInput = YES; label2.text =@""; NSString *path = [[NSBundle mainBundle] pathForResource:@"button5" ofType:@"wav"]; NSURL *url = [NSURL fileURLWithPath:path]; AVAudioPlayer *audio = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil]; [audio play]; } /* // Override to allow orientations other than the default portrait orientation. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations. return (interfaceOrientation == UIInterfaceOrientationPortrait); } */ - (void)didReceiveMemoryWarning { // Releases the view if it doesn't have a superview. [super didReceiveMemoryWarning]; // Release any cached data, images, etc. that aren't in use. } - (void)viewDidUnload { [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [super dealloc]; } @end

  • iPhoneアプリ開発 ファイル書き込み

    iPhoneアプリ開発につきまして、質問させて頂きます。 csvファイルへのデータの出力を試みているのですが上手くできません。 プログラムとログ内容を以下に記述しました。 「abc」と予め書いてある「hoge.csv」ファイルに「stringaaaaaaaaaaa」を書き込み保存しておきたいのですが、上手くいきません。 ログ内容を見る限り、「abc」が読み込めているので、パスは合っていると思っています。また、writeToFileをしてから読み込むと「stringaaaaaaaaaaa」が読み込めるため、どこかには書き込めているような気がします。 しかし、毎回同じ処理をしても、最初に読み込まれるのは「abc」です。「hoge.csv」をテキストエディタで読み込んでも表示されるのは「abc」です。 また、iPhoneシミュレーターで実行した結果は以下のログ内容なのですが、iPhone実機で動作させると、writeToFileを行ったあとでも「abc」が出力されます。 何か原因を思い当たる方、教えて頂ければ幸いです。 - (void)viewDidLoad { [super viewDidLoad]; [self setTitle:@"Stress Application"]; printf("viewdidload"); NSString *text = [[NSString alloc] initWithFormat:@"stringaaaaaaaaaaaaaaa"]; NSString *_path = [[NSBundle mainBundle] pathForResource:@"hoge" ofType:@"csv"]; //atomicallyは補助ファイルを使ってファイルの破損を防止するかどうか NSLog(@"%@",[NSString stringWithContentsOfFile:_path encoding:NSUTF8StringEncoding error:nil]); [text writeToFile:_path atomically:YES encoding:NSUTF8StringEncoding error:nil]; NSLog(@"%@",[NSString stringWithContentsOfFile:_path encoding:NSUTF8StringEncoding error:nil]); NSLog(@"%@",text); } <ログ内容> 2012-10-31 12:35:10.187 ThinkGearTouch[17182:1a903] FinishLaunching viewdidload2012-10-31 12:35:10.204 ThinkGearTouch[17182:1a903] abc 2012-10-31 12:35:10.212 ThinkGearTouch[17182:1a903] stringaaaaaaaaaaaaaaa 2012-10-31 12:35:10.212 ThinkGearTouch[17182:1a903] stringaaaaaaaaaaaaaaa

  • Objective-Cのメモリ管理について

    iPhoneのUIBarButtonItem(右上のボタン)を押すと、xamppのPHPで作ったwebサーバーにPOSTを送り、送ったPOSTの内容で異なるデータをiPhoneに返す仕組を作っていたら、Objective-Cのメモリ管理でつまづきました。 どうすれば以下のソースにあるNSString *strがメモリ解放されないかを知りたいです。 【ソース】 - (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data { //PHPのデータ char* p = (char*)[data bytes]; NSString *str = [[NSString alloc] initWithUTF8String:p]; NSLog(@"str_RETAIN:%d",[str retainCount]); ←問題の箇所 NSRange rng; rng = [str rangeOfString:@"比較したい文字列"]; if(rng.length > 0) ...以下、strに関係する部分はないので省略 } この時、NSStringでalloc,initWithUTF8Stringを呼び出した後のNSLogのretainCountは呼び出すたびに常に1が出るようにしたいのですが、なぜか0になったり1になったりしてしまいます。 コンソール画面で何度も試しましたが、0になったり1になったりするのに法則性がなく、最初0で次押すと1,1,1,0,1,1,0とか、最初1,0,1,0,0,1,1,1,1,1...など、乱数のような状況になってます。 なので、0になった場合は、セットした値が無くなってしまっていて、次の部分文字列の比較(rng = [str rangeOfString:@"比較したい文字列"];)の部分で正しい動作ができなくなってしまってます。 送られてくるPHPのデータ(char *)は特に問題なさそうです。 後、サーバーに接続出来ない場合は、別の処理でエラー判定が出来るようになっているので、最初からデータがないという事はないです。 分かる方いましたら、ご回答お願いします。

  • xcodeの音を鳴らすのを遅らせる方法

    xcodeで音を鳴らしたいんですけど、 ボタンを押して数秒したら音が鳴るようにしたいんですけどどうしたらいいでしょうか? ループさせるので音源の最初を空白にするわけにはいきません。 あとAVAudioPlayerを使ったやり方だと助かります。 NSString *bgmPath = [[NSBundle mainBundle] pathForResource:@"music"ofType:@"mp3"]; NSURL *bgmUrl = [NSURL fileURLWithPath:bgmPath]; sound = [[AVAudioPlayer alloc] initWithContentsOfURL:bgmUrl error:nil]; [sound setNumberOfLoops:0]; //ここに指定した時間遅らせるというのを入れたい// [sound play]; どうかよろしくお願いします。

  • core audio

    すみません教えてください 以下のコードでエラーが出てしまいます なぜでしょうか? よろしくおねがいします OSStatus result = noErr; char *ParentName; FSRef inParentRef; NSString *inFileName; AudioStreamBasicDescription inFormat; FSRef outNewFileRef; AudioFileID outAudioFile; ParentName = "/Users/hoge/AudioFile"; result = FSPathMakeRef ((const UInt8 *)ParentName, &inParentRef, NULL); if(noErr != result ){ NSLog(@"FSPathMakeRef [error]"); }else{ NSLog(@"FSPathMakeRef No error"); } inFormat.mFormatID = kAudioFormatLinearPCM; inFormat.mSampleRate = 32000.0; inFormat.mFormatFlags = 0; inFormat.mBytesPerPacket = 4; inFormat.mFramesPerPacket = 1; inFormat.mBytesPerFrame = 4; inFormat.mChannelsPerFrame = 1; inFormat.mBitsPerChannel = 16; inFileName = @"MySong.aif"; result = AudioFileCreate( &inParentRef, (CFStringRef)inFileName, kAudioFileAIFFType, &inFormat, 0, &outNewFileRef, &outAudioFile); if(noErr != result ){ NSLog(@"AudioFileCreate [error]"); }else{ NSLog(@"AudioFileCreate No error"); }

専門家に質問してみよう