• 締切済み

C言語でのCSVソートとデータ抽出について

noname#144013の回答

noname#144013
noname#144013
回答No.5

こんにちは。 処理の概略手順だけ考えてみました。 ※下記は一例です。 1)入力元CSVファイルをオープンする。 2)入力元のCSVファイルを行単位に読み込み、その行数のみ取得する。   ・fgets関数で、最大バッファ長を (2048+4)ぐらいとして、行単位に[EOF]    になるまで読み込んで(※ここでは文字列バッファに読み込むのみ)、    行数(レコード数)をカウントする。   ・読み込んだ1行分の文字列の末尾の改行文字('\n')を除いた文字数が    2048文字を超えた行は無視する。(※カウントしない)  <行数(レコード数)を格納する変数の例>   long nRecCnt;  ← 取得した行数(レコード数)を格納する。 3)取得した行数分の、データ構造体(1レコード相当)の配列を確保する。  <1レコード分のデータ構造体の例>   typedef struct TT_DATA {     long nNum;        /* 1カラム目の数値データ用 */     char szItem[256];    /* 2カラム目の文字列データ用 */     char szOther[2048];  /* 3カラム目以降のデータ用 */     int nOutFlag;      /* CSV出力の識別フラグ */   } T_DATA;   ※上記の文字列データのサイズは適当に割り振ってあります。     実際は、仕様に合わせて調整する必要があります。   ※3カラム目以降のデータは、プログラム上で編集する必要がないので、    1つの文字列として取り込むように、1つのバッファにしてあります。   ※CSV出力の識別フラグ(nOutFlag)は、出力CSVファイルに書き込む    レコードを識別するためのフラグに使用します。   上記の構造体の場合で、行数分(レコード数分)の配列を確保する場合、     T_DATA *t_data;     t_data = (T_DATA *)malloc( sizeof(T_DATA) * nRecCnt );     ※nRecCnt は取得した行数(レコード数)   のような感じになります。 4)入力元のCSVファイルのファイルポインタを先頭に戻して(先頭へシークする)   再び、1行毎に読み込みながら、3)で確保した構造体配列に、全行数分の   データを格納する。   ・読み込んだ1行分の文字列の末尾の改行文字('\n')を除いた文字数が、    2048文字を超えた行は無視する。(※データは取り込まない)   ・1カラム目のデータは、「数字文字列→数値」変換を行い、.nNum に格納する。   ・2カラム目のデータは、.szItem[] に格納する。   ・3カラム目以降のデータは、1つの文字列として、.szOther[] に格納する。   ・データ構造体の「CSV出力の識別フラグ」(.nOutFlag)は、0 でクリアしておく。 5)入力CSVファイルをクローズする。 6)データを取り込んだ、構造体配列に対して、2カラム目のデータ(文字列)をキー   にしてソート処理を行い、並び替える。   ・文字列の大小判定は、strcmp関数で判定可能かと思います。 7)ソート後の構造体配列の先頭からデータを参照し、2カラム目の文字列が   同じものについて、1カラム目の数値が最大のものを抽出し、     「CSV出力の識別フラグ」(.nOutFlag)に 1 を立てる   処理を行う。 8)出力CSVファイルをオープンする。 9)データ構造体配列を先頭から参照し、「CSV出力の識別フラグ」が 1 のもの   について、出力CSVファイルに書き込む処理を行う。 10)出力CSVファイルをクローズする。 11)確保したメモリを解放して、プログラムを終了する。 以上のような処理が考えられると思います。 的外れだった場合はすみません。 参考になれば幸いです。

tukihiro
質問者

お礼

おはようございます。 ご回答有難う御座います。 どのような手順で作成したらいいのかさっぱりでしたので 大変参考になりました。 この週末になんとかご提示頂いた手順でC言語の参考書を読みながら コーディング出来るように努力してみます。 本当に有難う御座いました。

関連するQ&A

  • 時刻表を分でソートする方法を教えてもらえませんか?

    NextTrainと言う時刻表表示ソフトを使っているのですが 7種類の時刻表を1つの時刻表ファイルにまとめて 一度で見れるようにしたいのです。 peal初めてで色々と読んでみてもよく解りませんでした。 今の状況は、ActivePerl 5.10.0.1003 をセットアップして、  『Hello World』を表示させる事は出来ました。 『例として6時から8時までをソートしてみます』 【分でソート前】 06: a22 a52  b07 c25 c47 c58 c51   d25    e55 07: a12 a30 a40 a49 a58 c09 c21 c34 c46 c59 d13 d24 d37 d49 e15 e34 e44 e53 08: a07 a17 a28 a38 a47 b04 b45 c12 c25 c38 c51 d02 d21 d32 d42 e58 【分でソート完了】 06: b07 a22 c25 d25 c47 c51 a52 e55 c58 07: c09 a12 d13 e15 c21 d24 a30 c34 e34 d37 a40 e44 c46 a49 d49 e53 a58 c59 08: d02 b04 a07 c12 a17 d21 c25 a28 d32 a38 c38 d42 b45 a47 c51 e58  ※分の前に付いているアルファベットはバスの系統なので必ず付きます。   Perlで無くても簡単に出来る方法があれば教えてください。   アドバイスよろしくお願いします。

    • ベストアンサー
    • Perl
  • 複数のcsvファイルをマクロ(VBA)で取り込みたい

    複数のcsvファイルをマクロ(VBA)で取り込みたい csvファイルの中身が、 20090507 120508 osaka 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 b1,b2,b3,・・・・・,b10 c1,c2,c3,・・・・・,c10 や 20090507 132529 hokkaido 項目1,項目2,項目3,・・・・・,項目10 d1,d2,d3,・・・・・,d10 e1,e2,e3,・・・・・,e10 f1,f2,f3,・・・・・,f10 となっているcsvファイルが特定のフォルダの中に100以上あります。 このcsvふぁいるの5行目だけをaccessに書き込んでテーブルに追加していきたいと思っています。 項目1,項目2,項目3,・・・・・,項目10 a1,a2,a3,・・・・・,a10 d1,d2,d3,・・・・・,d10 このようなテーブルができればいいのですが・・・ csvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する)→次のcsvファイルを開く→5行目をテーブルに追加→csvファイルを閉じる(削除する) この流れでいいと思うのですが方法が分かりません。 丸投げですがよろしくお願いします。

  • C言語のCSV形式からのソート

    C言語初心者です。 C言語でCSV形式のテキストファイルを読み込み そのファイルの内容(数値)を昇順にソートして表示するプログラムを作りたいのですが中々上手く行きません・・・。 調べても分からず困っています。 どなたか教えていただけませんか?

  • csvデータの置換について

    お世話になります。 batファイルを利用してcsvファイルの数値の置換をしたのですが、ご教授下さい。 詳細は下記になります。 【環境】 Windows2008 Server 【対象ファイル】 test.csv 【実施内容】 ファイルの内容は下記になります。 A,111,aaa B,222,bbb C,333,ccc D,444,ddd E,555,eee 上記の内容で数値を下記のように置換したい。 111は111F 222は222G 333は333H 444は444I 555は555J よろしくお願い致します。

  • 巨大なCSVの加工(指定列のみの抽出)について

    巨大なCSVの加工(指定列のみの抽出)について 下記のような構成のCSVファイルがあります。 "ID","a","b","c","d","e","f","g","h","i","j","k","l","m" "0001","a","b","c","d","e","f","g","h","i","j","k","l","m" "0003","a","b","c","d","e","f","g","h","i","j","k","l","m" "0004","a","b","c","d","e","f","g","h","i","j","k","l","m" ・ ・ ・ 例えば、 ここから"ID"列と"c"列と"f"列のみ抽出して新たなCSVファイルで保存。 という処理を行いたいのですが、行数が5000万行近くあり、ファイルサイズが80GB程あるので エクセルはおろかアクセスでも開くことができません。 テキストエディタの秀丸64bit版なら開くことができますが、指定列の抽出方法が分かりません。 秀丸のマクロでもVBSでも良く、また膨大な待ち時間がかかっても構わないので実現する方法について お知恵をお貸しください。

  • CSVから値の割り出し

    CSVファイルの1行目を渡された引数から値を割り出し、配列(@x)に 格納して、2行目以降も1行目で評価された要素と同じ位置の要素を 別配列(@y,@z)に入れて、渡された複数の引数をもとに下記のように 評価したいのですが可能ですか? 例)CSVファイル:1レコード目:1,1,1,2,2,2,3,3,3        2レコード目:1,2,3,4,5,6,7,8,9        3レコード目:A,B,C,D,E,F,G,H,I 引数:2,3,1なら 結果:2,6,D   @x=2,2,2 @y=4,5,6 @z=D,E,F

    • ベストアンサー
    • Perl
  • csvファイルからデータを抽出したい

    はじめまして。VBA初心者です。 【元となるデータの入ったCSVファイル(改竄禁止)】     A    B    C    D    E 1  ○位  名称  県名 住所 電話番号 2  ×位  ・・・ 3  △位  ・・・ 【抽出したデータを書き出したいxlsmファイル】     B    C 2  順位  3  県名 この二つのファイルがあるのですが、 (1)xlsmファイルのC2に順位を入力し、その順位の建物のデータを  csvファイルから抜き出し、xlsmファイル同シートのB5:F5に表示 (2)同じく県名もC3に入力し、抜き出した結果をB7を左上隅として表示 したいと思っています。 検索や本を見ましたが、似たようなケースがあってもそこから自分で 作るということができませんでした; 今後の参考にもしたいので、もしよろしければコードの解説もよろしく お願いします。

  • phpで、可変項目のcsvデータを読み込みたい

    csvでデータを読み込む方法はネットで見つけたのですが、下記の条件を加えた場合どうすればいいか分かりません。 ネットで見つけた方法は、ファイルを1行ごと読み込み、コンマごとに区切って配列にいれる方法です。 しかし、項目が可変の場合、名前を入れたいところに別のデータが入ったりします。 【条件】 csvの項目名は、 A,B,C,D,E,F とする それぞれの項目は、省略可能(どこが省略されるか分からない) そのため、 A,D,E,F など、項目名が少ないCSVファイルもある。 こんな場合は、どのように処理をすればよいでしょうか? 実際は、項目名が50個ほどあります。 今回の例のように、少なければ何とかできそうなのですが・・・ 【補足・データファイル】 "A","B","C","D","E","F",←項目名 "山田","太郎","東京","15","123-221","男",←データ "山田","次郎","東京","13","124-567","男", ・・・・・・・・・↓続く ・・・・・・・・・

    • ベストアンサー
    • PHP
  • C言語

    main() { int a = 5,b=2,e,f,g=3,i; double c,d,h=2.0; c = a/b; printf("c = %f\n",c); d = a/h; printf("d=%f\n",d); e = a++; f = ++b; g+= 4; i= ++a + b; printf(" a = %d\n",a); printf(" b = %d\n"b); printf(" e = %d\n"e); printf(" f = %d\n"f); printf(" g = %d\n"g); printf(" i = %d\n" i); 答え a=7,b=3,c=2.0,d=2.5,e=5,f=3,g=7,i=10 この問題のa,b,iがどうやってこの値になるのかがわかりません解説お願いします。

  • C言語 CSVファイルの読み込み

    前回の質問が説明不足だった為、こちらでもう一度詳しく補足を加え再度質問させていただきます。 ↓前回の質問 http://okwave.jp/qa/q6352672.html 読み込むCSVファイルは数値のみです。 具体的な例として数値をあげさせていただきます。 例:ファイル名 test.csv 10,1.1,1.2,1.3 20,2.1,2.2,2.3 30,3.1,3.2,3.3 上記のような4列3行のCSVファイルをC言語を使用し、 10→a 1.1→b 1.2→c 1.3→d 20→e 2.1→f 2.2→g 2.3→h 30→i 3.1→j 3.2→k 3.3→l といった具合に、任意の列・行の数字を任意の場所へ読み込みをするということが出来ません。 例をプログラムにするとどのようになるのか教えていただきたいです。 よろしくお願いします。