ページ 11

csvファイルの読み込み

Posted: 2009年4月14日(火) 21:54
by ラジオ
csvファイルを二次元配列に読み込みたいです。

添付してあるファイルの1行目1文字目の数字が配列の大きさです。
添付したものでは8となっているので

int num[8][2]という変数を作りたいです。
そのあとに以下のように読み込みをしたいです。
num[0][0] = 1;
num[0][1] = あいう;
num[1][0] = 2;
num[1][1] = いう;

また文字列を扱ったりしますので
typedef struct{
int num;
char text;
}TEST;

TEST test[8];

と書こうかとも考えています

仕事や学校の課題などではなくシスアドの勉強をしていてcsvに興味がわきましたので質問させてもらいました。
いろいろなサイトをみてcsvの読み込むヘッダがあるらしいのですが理解できませんでした・・・
お手数おかけしますがどうかご教授ください。
VisualStadio2005 XP C++ DOS
添付内容

8,8
1,あいう
2,いう
3,うえおか
4,えお
5,お
1,
3,あいう
4,さし

Re:csvファイルの読み込み

Posted: 2009年4月14日(火) 22:00
by non
意味がわからないので、補足をお願いします。
>num[0][1] = あいう;
これは、何をしたいのでしょうか?

結局、質問内容はなんでしょう?

Re:csvファイルの読み込み

Posted: 2009年4月14日(火) 22:04
by kazuoni
>int num[8][2]という変数を作りたいです。
>そのあとに以下のように読み込みをしたいです。

num[0][0] = 1;
は文字列を読み終わった後にatoiに渡せばできますが、

num[0][1] = あいう;
はできません。num[0][1]はint型ですので。

後者なら可能です。
一行目は(8,8)が何を示しているのかが良く分かりませんが、
二行目以降なら、改行文字が現れたら配列の要素を進めていく
っとすれば大丈夫です。(または自分で終端文字を決めるもありです。)

補足
char text;
ではだめなので、ポインタ、文字列あたりを復習してください。

Re:csvファイルの読み込み

Posted: 2009年4月14日(火) 22:18
by box
> csvファイルを二次元配列に読み込みたいです。

構造体の配列をお使いになるのがよいでしょう。
その際、

> TEST test[8];

配列の要素数が8であるかどうかは、
CSVファイルの1行目を読んだときにわかります。
したがって、上記のような固定数での定義は適切ではありません。
CSVファイルの1行目を読んで、要素数が8を超えるとわかったとたんに
破綻しますよね。

CSVファイルの1行目の内容に応じて、
必要な領域をプログラム実行時に動的に確保する方法がよいでしょう。
そこで、malloc, freeといった、動的確保・開放を行なう関数について
調べてみるとよいでしょう。

Re:csvファイルの読み込み

Posted: 2009年4月14日(火) 22:27
by ラジオ
>>nonさん
>>結局、質問内容はなんでしょう?

気になっただけなんです・・・

>>kazuoniさん
>>一行目は(8,8)が何を示しているのかが良く分かりませんが

すいません><
適当にかいただけですので気にしないでください・・・
実際はエキセルで一番上の行にカウント関数かいただけです><

>>boxさん
>>配列の要素数が8であるかどうかは~

もちろん変更しようかと考えています。
一番上の行の数字+4くらい余分に取る予定です。

テキストの読み込みはできるのですがcsvになると
どうやるのかわからないんです・・・。
一応ただ文字を読み込むソースを書いたものを添付してみます

Re:csvファイルの読み込み

Posted: 2009年4月15日(水) 23:04
by ラジオ
いろいろと試してみたのですができないみたいです・・・。

Re:csvファイルの読み込み

Posted: 2009年4月16日(木) 11:34
by kazuoni
「できない」だと回答する側は何も答えようがないので、
もっと症状を細かく説明するなり、
試したものをアップするとよい回答が得られると思います。

Re:csvファイルの読み込み

Posted: 2009年4月16日(木) 12:42
by たかぎ
CSVの解析は思っているほど簡単ではありません。
面倒なのは、フィールドが二重引用符で囲まれていた場合で、

・二重引用符に囲まれた文字列にコンマが含まれる場合、そのコンマはフィールドの一部とみなす。
・二重引用符に囲まれた文字列に連続した二重引用符が含まれる場合、ひとつの二重引用符とみなす。
・二重引用符に囲まれた文字列に改行文字が含まれる場合、その改行文字はフィールドの一部である。

というルールがあります。
また、http://www.ietf.org/rfc/rfc4180.txtでは、0x20~0x7e(および改行文字)以外をフィールドに含めることができません(この仕様は公然と無視されていますが...)。

Re:csvファイルの読み込み

Posted: 2009年4月16日(木) 17:36
by non
ラジオさんの添付ファイルを見ると二重引用符では囲まれていないので、カンマ区切りで分割
できるかどうかということだと思います。
作ったプログラムを添付してみてください。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 00:28
by ラジオ
皆様、回答ありがとうございます。

添付したソースは1行しか読み込みができないです・・・。
これくらいしかテキストの読み込み方がわかりません・・・

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 08:45
by たかぎ
> ラジオさんの添付ファイルを見ると二重引用符では囲まれていないので、カンマ区切りで分割
> できるかどうかということだと思います。

このデータに決め打ちしてよいなら簡単ですね。
極論をいえば、ファイルを読み込む必要すらありません。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 09:05
by non
>極論をいえば、ファイルを読み込む必要すらありません。

答えを聞きたい!!

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 10:44
by toyo
極論ですから
ファイルの内容がわかっているならソースに直接埋め込めば良いという意味でしょう

char *test_dat = "8,8\n1,あいう\n2,いう\n3,うえおか\n4,えお\n5,お\n1,\n3,あいう\n4,さし\n";

みたいな

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 12:15
by non
>ファイルの内容がわかっているならソースに直接埋め込めば良いという意味でしょう

それは、趣旨が違っているのではないでしょうか?

>このデータに決め打ちしてよいなら簡単ですね。

2重引用符がない、カンマ区切りのcsv形式というデータ形式に決め打ちかと思いました。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 17:59
by たかぎ
> それは、趣旨が違っているのではないでしょうか?

CSVファイルを二次元配列に読み込みたいという質問なので、趣旨が違っているといえばそうです。
けれども、CSVファイルであれば二重引用符に配慮するのは当然ですので、それを無視した回答も同じように趣旨が違っています。

なお、真の目的が、決め打ちのデータを二次元配列に格納することが目的であれば、ファイルからの読み込みではなく、ソースファイルに埋め込む方法も検討の余地が十分にあります。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 23:05
by ラジオ
みなさん回答ありがとうございます。
私の説明が不足していましたね。

やろうとしていることは
ユーザーがエキセルなどを使い2列にわたり
様々な数値や文字列を入れます。

列・・・縦軸下方向 行・・・横軸右方向

しかし、この時に一番上の行の2列は使われず
1列に何行あるかをカウントします。 ←numとします
2行目から下に向かって値があります。

これを用意した
Array[num][2];
配列にいれたいのです。

ファイルの中身はユーザが決めるのであらかじめ数なども含めわかりません。
ただし必ず2列?行になります。

わかりにくい質問ですいません。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 23:50
by kazuoni
とりあえず一行しか読み込めないっというのは克服できていませんか?
fgetc、fgetなどを調べて使って、テキストファイルから読みとってみてください。
それでカンマがくるまで読み取った文字を配列に代入する
っということができればやりたいことがなんとなく実現できるような気がします。
そうすれば「二重引用符」を考慮しないcsv形式ファイルからの読み込みなら実現できそうです。
(こんなこと書いてしまうと、↑のレスの皆様の議論が水の泡になってしまいそうですが・・・^^;)

>Array[num][2];
numが変数なので、動的確保でないと実現できません。
先頭に全部の行数を記述し、読みとり、そこから動的確保をするか、
ある程度大きい配列を確保するのどちらかになるかと思います。

Re:csvファイルの読み込み

Posted: 2009年4月17日(金) 23:53
by SooA
完全に入力制限してしまうのなら

fgets  ストリームから文字列の取得
strtok  文字列のトークン切り出し

といった関数を使って読み込ませることは簡単です。


>これを用意した
>Array[num][2];
>配列にいれたいのです。

変数に関してあまり理解できていないようなので、
↓のC言語編24章前後を読み進めてみましょう。
http://www.geocities.jp/ky_webid/index_old.html