• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:c言語プログラムについて)

C言語プログラム:ファイルのダウンロードと読み込み後の処理について

このQ&Aのポイント
  • C言語プログラムで、全国一括の郵便番号データをダウンロードし、指定の住所から郵便番号を特定するプログラムを作成する方法を教えてください。
  • 使用OSはFedoraです。ソースコードは提供されており、ファイルのダウンロードと読み込みまでは成功していますが、どのようにして指定の住所から郵便番号を抽出するかわかりません。
  • ソースコードには郵便番号データが含まれており、配列に格納されています。具体的な処理の方法や関数の使用方法を教えていただけると助かります。

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

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

#2です。#2では、あちらのサイトを参照して回答させて頂きました。 http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1439205919 まだ、投稿は有効なようですから、ROMの方のために、もう一つの専用プログラムを載せて置きます。  なお、kterm のない Mac ユーザーは CSVファイル(ken_all.csv)と次のスクリプトファイルを作成し、 #!/bin/bash # file name: number_search.sh ./a.out "北海道札幌市中央区旭ケ丘" ターミナルから「bash number_search.sh」と入力、起動してください。 /* An answer by Gcc on Mac OSX * file name: nard2.c * compile: gcc nard2.c * execution: ./a.out "北海道札幌市中央区旭ケ丘" * * --- Using CSV file --- * 01101,064,0640941,ホッカイドウ,サッポロシチュウオウク,アサヒガオカ,北海道,札幌市中央区,旭ケ丘,0,0,1,0,0,0 * 01101,060,0600041,ホッカイドウ,サッポロシチュウオウク,オオドオリヒガシ,北海道,札幌市中央区,大通東,0,0,1,0,0,0 * .... */ #include <stdio.h> #include <stdlib.h> #include <string.h> #define FILE_NAME "ken_all.csv" #define SIZE 256 #define ADD_N 2 char *search_ptr(char *, int); char *catstr(char *, int); int main(int argc, char *argv[]) { char *address, *number, buff[SIZE]; int flag=1; FILE* fp; if(argc != 2) printf("Parameter error\n"),exit(1); address = argv[--argc]; if((fp=fopen(FILE_NAME,"r"))==NULL) perror("fopen"),exit(1); while(fgets(buff,SIZE,fp) != NULL) { number=strtok(search_ptr(buff,2),","); if ((flag=strcmp(catstr(search_ptr(NULL,3),ADD_N),address))==0) break; } fclose(fp); flag ? printf("No correspondence.\n") : printf("No.%s\n",number); return 0; } char *search_ptr(char *b, int n) { static char *a; if (b!=NULL) a=b; while(n--) while(*a != '\n' && *a++ != ','); return a; } char *catstr(char *p, int n) { char *t,*b; b=p; while(*p++ != ','); t=p-1; while(n--){ while((*t++ = *p++) != ','); --t; } *t='\0'; return b; }

その他の回答 (3)

回答No.4

#2 です。 >hiroshi09s様のソースを参考にコンパイルして実行してみましたが、「Segmentation fault」になってしまいました。何が原因と考えられるのでしょうか?  通常は、設定変数メモリ枠を超えたアクセス(読み書き)に発生し、そのエラーを「Segmentation fault」と知らせてくれます。 >お礼の所ですいません。動いてはいるみたいですが、正しい結果が出るのは最初の3件(北海道札幌市中央区大通東)までで、残りは「Segmentation fault」なってしまいます。 ・・・ということは、2~3件目において動いているならば10件になろうと100件、1000件になろうと同じですから、そのことを配慮すれば、あなたの提示したCSVファイルの内容(書式)が4件目から違っていると思われます。したがって、データについて、更に3~6件目くらいのCVSの内容を同じ展開になっているのかチェックする必要があります。  それともう1つ考えられるのは while(fgets(buff,SIZE,fp) != NULL) { setstr(line.dummy,buff); setstr(line.head_num,NULL); の setstr() における buff と NULL の使い方です。strtok() は「 static char * 」を使っているため、fgets() 直後の setstr() は NULL ではなく、きちんと「 buff である」とスタート位置を示す必要があります。単に NULL を続けると容量をオーバーし「Segmentation fault」となります。

nardobrea
質問者

補足

こんにちは 何が原因だったのかいまいちよくわかりませんでしたが、 1つの可能性としてcsvファイルの半角カタカナの読みデータを全角カタカナのものに変更したら何故かどの住所でも結果を返してくれました あと、今回は無かったのですが、strtokの性質でカンマ区切りが連続で出てしまった時、例えばken_all.csvの2行目が 01101,,0640941,ホッカイドウ,サッポロシチュウオウク,アサヒガオカ,北海道,札幌市中央区,旭ケ丘,0,0,1,0,0 のようになっていた時、head_numに0640941が入って、all_numにホッカイドウが入って…と同様にして1つずつずれてしまい、最終的に北海道札幌市中央区旭ケ丘と検索すると「該当しない」とになってしまうような気がするのですが… カンマ続きのファイルがあるときの対策ってあるのでしょうか? こちらから一方的に質問ばかりですみません

回答No.2

 当方、Mac OSX です。若干のプログラムミスがあるかも知れませんが、参考になれば幸いです。 /* An answer by Gcc on Mac OSX * file name: nard.c * compile: gcc nard.c * execution: ./a.out "住所" */ #include <stdio.h> #include <stdlib.h> //exit() #include <string.h> //strcmp() #define FILE_NAME "ken_all.csv" #define SIZE 512 #define setstr(x,z) {strcpy(x,strtok(z,","));} struct set{ char dummy[32], head_num[4], all_num[8], kana1[32], kana2[32], kana3[32], kanji1[32], kanji2[32], kanji3[32]; }; int main(int argc, char *argv[]) { struct set line; FILE* fp; char *address, buff[SIZE], string_buff[SIZE]; int flag=0; if(argc != 2) { printf("引数が違います。\n"); return 0; } address = argv[--argc]; if((fp=fopen(FILE_NAME,"r"))==NULL){ perror("fopen"); exit(1); } while(fgets(buff,SIZE,fp) != NULL) { //各項目の設定 setstr(line.dummy,buff); setstr(line.head_num,NULL); setstr(line.all_num,NULL); setstr(line.kana1,NULL); setstr(line.kana2,NULL); setstr(line.kana3,NULL); setstr(line.kanji1,NULL); setstr(line.kanji2,NULL); setstr(line.kanji3,NULL); //文字の連結 strcpy(string_buff,line.kanji1); strcat(string_buff,line.kanji2); strcat(string_buff,line.kanji3); //文字列の比較 if (strcmp(string_buff,address)==0) { printf("〒%s\n",line.all_num); flag=1; break; } } fclose(fp); if (flag==0) printf("該当なし\n"); return(0); }

nardobrea
質問者

お礼

お礼の所ですいません。動いてはいるみたいですが、正しい結果が出るのは最初の3件(北海道札幌市中央区大通東)までで、 残りは「Segmentation fault」なってしまいます。

nardobrea
質問者

補足

返事が遅くなり申し訳ありませんでした。hiroshi09s様のソースを参考にコンパイルして実行してみましたが、 「Segmentation fault」になってしまいました。何が原因と考えられるのでしょうか?

  • notnot
  • ベストアンサー率47% (4900/10360)
回答No.1

コマンドラインの引数を参照するのは、 int main(int argc, char **argv) としておいて、argv[1] が引数です。( argc > 1 のとき ) 文字列の比較は、strcmp関数を使います。 Cの標準関数リファレンスは(細かく覚えなくて良いので)一度通読しましょう。

nardobrea
質問者

補足

返答ありがとうございます。strcmpについて学習してみましたが、 どうもそれだけでは上手くいかないようですね… 読み込んだcsvファイルを配列に格納したいのですが、その辺もできなくて頭打ち状態です。 構想としては (1)各行でカンマ区切りで各データを配列で格納し、 (2)7,8,9列目のデータ(漢字データ)を一つにつなげて (3)入力された引数と(2)でつなげたデータを1つずつ比較して、←ここでstrcmp使用でしょうか? (4)一致したのがあれば3列目の郵便番号を返す としています。

関連するQ&A

専門家に質問してみよう