- 締切済み
コンマで区切られた、数値と文字列を含むファイルの入出力(C言語)
C言語に関する質問があります。 数値と文字列を含む外部ファイルを読み込みたいのですが、方法が分かりません。もし良いアイディアを思いついた方、頭の良い方はぜひ回答よろしくお願いします。 外部ファイルは、以下のデータを1セットとして、この1セットのデータが改行されて、何千行もあるファイルです。 1セットのデータは41個の属性からなり、コンマで区切られています。 文字列のデータと、数値データ(連続値)からなります。 0,tcp,smtp,SF,829,327,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,8,113,0.88,0.25,0.12,0.02,0.00,0.00,0.00,0.00 ↓ 0,udp,private,SF,105,146,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,255,253,0.99,0.01,0.00,0.00,0.00,0.00,0.00,0.00 ↓ . . . のように時系列データとなっています。 配列data[41]を用意し、41個のデータを data[0] = 0 data[1] = tcp data[2] = smtp data[3] = SF data[4] = 829 . . . のように配列に入れたいと考えています。 *配列に格納されているデータを計算で使うため、配列を使いたいと考え ています。 上記の方法が可能か分かりませんが・・・ 当方まったくの初心者で困っています。よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- Interest
- ベストアンサー率31% (207/659)
データが文字列と数字を含んでいるので、構造体を使いたいですね。 構造体のメンバに名前を付けたいので、各行に入っているデータの意味を教えていただけますか? 構造体は、例えば、 struct{ char hoge; /* 0ってなに?*/ char transport[4]; /* tcp/udp */ char application[7]; /* smtp, private */ char fuga; /* SFってなに?*/ ・・・ char member41; /* 変数の意味が分からないので。*/ } hogeData; とします。 数字データの値の範囲はマイナスを含みますか? 少数で扱っているものは、小数点以下2桁固定ですか? ここら辺はわざわざ float を使わなくても数値を100倍してunsigned char の変数に押し込める可能性があります。そうすればメモリの消費量を抑えられますよね。 > 外部ファイルは、以下のデータを1セットとして、 > この1セットのデータが改行されて、何千行もあるファイルです。 こういう場合は、malloc などを用いてメモリの動的確保を行いましょう。 数千行もある配列を用意することは現実的ではありません。ポインタについて学ぶとメモリの動的確保の話が必ず出てきます。プログラム中でファイルの行数をカウントして、必要な分だけメモリを確保しましょう。 (メモリの動的確保に関する参考URL) http://bi.appi.keio.ac.jp/seminar/c/node51.html http://www.birdport.jp/CGuide3/73/ ポインタについて理解されていないようでしたら、先にポインタについて「正しく」理解することを強くお勧めします。ポインタはC言語における強力な武器であり、致命的なバグを埋め込みやすい諸刃の剣でもあるからです。ポインタについて勉強される場合、お勧めの本があります。 秘伝C言語問答 ポインタ編、柴田 望洋 (著)、SOFTBANK BOOKS http://www.amazon.co.jp/exec/obidos/ASIN/4797302976/qid=1119955455/sr=1-14/ref=sr_1_2_14/250-7647891-7391437 この本には、当然メモリの動的確保の話も書いてあります。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
参考URLとほぼ同じ問題だと思います。 1行読み込んだ時点で計算処理するのでなく 全部の行を読み込んだ時点で計算するのであれば、 それだけのメモリを確保しないといけませんけど。
補足
ご丁寧な返答ありがとうございます。大変参考になります。データの意味を記入させていただきます。 実はこのデータはベンチマークデータで、コネクションの、ある時間で区切られるTCPパケットの系列であります。 このデータは、41個の属性(パラメータ)からなります。以下は一つのコネクションの例です。 0,tcp,smtp,SF,829,327,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,0.00,1.00,0.00,0.00,8,113,0.88,0.25,0.12,0.02,0.00,0.00,0.00,0.00 ↓ パラメータは順に、 duration:コネクションの長さ(秒) protocol_type:プロトコルの種類(tcp,udpなど) service:あて先のネットワークサービス(http,telnetなど) flag:コネクションの状態 src_bytes:送信元からあて先へのデータサイズ(バイト) dst_bytes:あて先から送信元へのデータサイズ(バイト) land:コネクションが同じポートから、または同じポートへ、の場合は1。奏でない場合は0。 wrong_fragment:不適切な断片の数 urgent:urgent packetの数 hot:"hot"を示したコネクションの数 num_failed_logins:ログイン失敗回数 . . . のようになっていますが、現段階では、まずは、duration,service,src_bytes,dst_bytesの4つの属性(パラメータ)を使いたいと考えています。 ですので、現段階では41個のデータのうち4つしか使いません。申し遅れてすいません。。。 したがって、数字のデータはマイナスをとることはありませんし、数値はすべて整数です。 duration(非負整数),service(シンボル値),src_bytes(非負整数),dst_bytes(非負整数) です。 私のイメージとしては、 一行のデータ列から、上記の4つのデータを取り出し、それを配列に格納し、計算する。→計算結果を別ファイルに出力する。→また一行読み込み、4つのデータを取り出し配列に格納後、計算。→その結果を別ファイルに出力する。→・・・ といった流れをイメージしていますが、可能でしょうか? もっと良い方法があれば、ぜひ教えてください。 お手数ですが、よろしくお願いします。