CSVを解析するコードを投稿せよ

このエントリーをはてなブックマークに追加
1仕様書無しさん
CSVを解析するエレガントなコードを投稿せよ。
CSVはExeclで読み込めるものとする。
C言語限定。
2仕様書無しさん:01/11/23 22:56
>>1
仕事は自分でやりましょう。
つかそのぐらい作れないのか?
3仕様書無しさん:01/11/23 22:57
学生だろ。
ほら、最終レポートの季節だからさ。
4仕様書無しさん:01/11/23 22:58
1です。
>>2

作ったよ。
でももっともっと良いコードがみたい。
プログラミング作法で取り上げられていたもの以上のものを。
5仕様書無しさん:01/11/23 23:00
だから、「プログラミング作法」が教科書だったんだろ。
それでレポートが「CSVのサンプルを改良せよ」じゃないのか?
ありがちだな。で、あげんな。
6仕様書無しさん:01/11/23 23:01
>>4
じゃあ、まずお前の書いたコードを
晒してみろよ。
7仕様書無しさん:01/11/23 23:03
仕事なら、perlでやれ。>>学生さん
8仕様書無しさん:01/11/23 23:04
>>1
ほらよ。

char *csv = "abc,def,ghi";

for(f = strtok(csv, ","); f != NULL; f = strtok(NULL, ",")) {
 printf("%s\n", f);
}
9仕様書無しさん:01/11/23 23:04
open "hoge.csv" for input as #1
do until eof(1)
input #1, a, b, c, e, f, g
loop
close #1
10なんとなく。:01/11/23 23:19
1がいいころあいに叩かれているので、自分のソースをUPしてくれると
盛り上がりそうで、何よりです。
11仕様書無しさん:01/11/23 23:20
Dim fso As Scripting.FileSystemObject
Dim tso As Scripting.TextStream
Dim fields() As String
Dim i As Long
Set fso = New Scripting.FileSystemObject
Set tso = fso.OpenTextFile("FOO.CSV")
Do Until tso.AtEndOfStream
fields = Split(tso.ReadLine, ",")
For i = LBound(fields) To UBound(fields) Step 1
' なんかすれ
Next
Erase fields
Loop
tso.Close
Set fso = Nothing
Set tso = Nothing
12仕様書無しさん:01/11/23 23:25
>>11
先生!質問です。
このperlのようなJavaのような言語がVBなんですか?
1311:01/11/23 23:30
>>12
これがかの有名なクソ VB だよ。
つか、

  ネタスレには sage

テストに出るからね。
14仕様書無しさん:01/11/23 23:30
ていうか解析?
15仕様書無しさん:01/11/23 23:32
abc,"def"",""ghi","jkl
mno
1612:01/11/23 23:34
>>13
わかりました!さげます!

テストが悪くても、出席点で救ってください!
先生の講義、最高でした!
17仕様書無しさん:01/11/23 23:36
Excelに解析させたら一番よい。
csvファイルを開かせてセルごとに読み取ればいいでしょ。
18仕様書無しさん:01/11/23 23:39
12さんよ 俺はPerlには見えなかった
12さんよ どのへんがPerlっぽいか教えてください
1912:01/11/23 23:43
>>18
split関数です!
それから変数の型もみんなDimだけかと思ったのであります!

このスレは「1を小馬鹿にするスレ」から「12をいぢめるスレ」に
変わったようです。

先生!もう寝ます!
20null:01/11/24 00:38
Javaで行毎にファイル読みこんでStringTokenizer使えば終了。
21仕様書無しさん:01/11/24 00:45
22仕様書無しさん:01/11/24 07:25
#!/usr/bin/awk -f
BEGIN {
  FS=",";
  printf("awk使えやゴルァ!\n");
}
{
  for (i = 1; i <= NF; i++)
  {
    printf("%s\n", $i);
  }
}
END {
  printf("あとは好きにしろ!\n");
}
23仕様書無しさん:01/11/24 09:37
>>1
セル内改行はあり か?
セル内に「,」はあり か?
セル内に「"」はあり か?
24仕様書無しさん:01/11/24 10:05
procedure AnalyzeCSV(aFileName: TFileName);
var
 i : Integer;
 slCSV : TStringList;
 slComma: TStringList;
begin
 slCSV :=TStringList.Create;
 slComma:=TStringList.Create;
 try
  slCSV.LoadFromFile(aFileName);
  for i:=0 to slCSV.Count-1 do
  begin
   slComma.Clear;
   slComma.CommaText:=slCSV[i];

   // なんかすれ

  end;
 finally
  slComma.Free;
  slCSV.Free;
 end;
end;
25仕様書無しさん:01/11/24 10:22
セル内にカンマやダブルコーテーション、改行があると
たちまち難易度があがりません?(ExecelCSV)
コードは書けるけどやっぱりスマートじゃないね。
26仕様書無しさん:01/11/24 10:27
セル内に改行があるCSVなんてあるの?
27仕様書無しさん:01/11/24 10:30
>>26
Excelならセル内に改行があるCSVも読めるよ!
28仕様書無しさん:01/11/24 10:31
>>27
知らなかった。
ダブルコーテーションでくくれば、改行があってもOKってこと?
29仕様書無しさん:01/11/24 10:37
>>28
ダブルコーテーションでセルくくるのは
セル内に
・カンマがある場合
・ダブルコーテーションがある場合
(セル内のダブルコーテーションは続けて2回書く)
だ。
改行は括らなくてもよい。
30仕様書無しさん:01/11/24 10:40
29の続き。
以上の事を考慮したらコードを書くのはそれなりのスキルが必要。
ガリガリ書けばどうにかなるが奇麗には書けん。<俺
31仕様書無しさん:01/11/24 10:43
>>29
改行がある場合は、行の終わりはどう表現されてるの?
32仕様書無しさん:01/11/24 10:45
>>24
DelphiのCommaTextって
スペースや、TABも区切りとして認識するから
使えないよう。
あと、誰も言及しないからオレの使い方がダメなのかも
しれないけど、最後のフィールドがNullだと
そのフィールドを認識しないから、ダメダメよ。
33仕様書無しさん:01/11/24 10:52
>>31
やっぱり改行で表現。
つーか、本来、CSVファイルって、改行で1レコードと
するわけだから、Excelや、FileMakerの改行のあるフィールド
ってのが方言と思ってしまう自分の融通のなさに
ちょっと自己嫌悪。
34仕様書無しさん:01/11/24 11:18
CSVの仕様書ってどっかにあるのかなあ。
前自分で読み込みルーチン作った時は、ひたすらクサそうなデータをExcelに
出力させて調べたんだけど、鬱になった。
35仕様書無しさん:01/11/24 11:24
>>34
CSVフォーマットの明示的な仕様ははっきり言ってない。
メーカーごとに違う。
いまはMSのCSVフォーマットが主流かな。
でも腐った仕様だな。プログラムで扱いにくい。
セル内のカンマは¥でエスケープする仕様ならスマートなのに・・・
なんで広まったんだろう。MSの力か?
36仕様書無しさん:01/11/24 11:33
>>35
CSVを読み書きしたい状況ってのは、やっぱExcelとのデータ交換が目的
の場合が多いからねえ。
「\」でのエスケープは、DOSのパス区切りとカチ合うから採用しなかったんじゃ
ないかと想像してみる。
3733:01/11/24 11:39
>>34-35
エクセルの普及なんだろうねぇ。
ただ、もともとはレコードをテキストで表現するのが発端だから
文字列区切りとしての"を利用するのであればそのフィールド
全部を"で括るのが正しいと思う。場当たり的にその問題個所だけ
"を入れたりするのはMSの得意な独自解釈・・・。
と、今さらながらテ料理本を探す自分にちょっと懐古趣味。
38仕様書無しさん:01/11/24 12:00
>>32
あ、やっぱ空の行は駄目なのね
if Trim(slCSV[i])<>'' then
でよろしく

これで実用上問題なかったよ
39仕様書無しさん:01/11/24 12:18
>>1
宿題は自分でやれよ。

=== 糸冬 了 ===
4039:01/11/24 12:18
あげちまった。
スマソ
41仕様書無しさん:01/11/24 13:15
Excelのセル内改行ってクセがあると思わない?
42仕様書無しさん:01/11/24 13:18
>>41
クセって?
43仕様書無しさん:01/11/24 13:23
>>42
エロいこと聞くな
44仕様書無しさん:01/11/24 13:40
>>42
Excel97/2000の場合なんだけど、
セル内改行があるときは、そのセルは""で括られる、というのは良
いのだけど、セル内の改行が、0x0A で表現されている。
CSVファイルの行末はDOS/Windows のテキストだから 0x0D 0x0A。

テキストモードでファイルオープンして書き込もうとしたらマズイ。

何のためにこういう仕様になってるんでしょ? それともOffice XP
だったら違う?
45仕様書無しさん:01/11/24 13:46
>>44
Excel 2000で試してみたところ、セル中の改行が0D 0Aになっても
問題なく読み込めたよ。
4642:01/11/24 13:53
>>44
レコードの終了と(セル内の)行末を区別したかったってトコでしょうかね。
47仕様書無しさん:01/11/24 13:56
>>45
さっそくの確認サンクス。
今はExcel 97+ Windows 2000の環境しか手元にないのだけど、
この環境ではセル内改行が 0D0Aになってると読み込んだときに
点が付く。Officeは新しい方が良いということか...
48仕様書無しさん:01/11/24 13:59
ExcelのCSVて嫌い。なんか独自仕様な部分がおおくてさ、
他のシステムで使えない場合が多いんだよね。

でも正しいCSVってどん何?だれか教えて、

数値のマイナス符号は前、後?
ダブルクォーテンションの表記は2度打ち?
カンマの場合は?
文字列に必ずダブルクォーテンションを括るのか?
値無しを認めるの?
などなど、、、。

固定長にカンマを差し込んだだけのCSVも見たことあるな...。
49仕様書無しさん:01/11/24 14:01
ExcelCSV(" , 改行含む)を解釈するスマートなコード見てみたい。
50仕様書無しさん:01/11/24 14:18
FileMakerの場合、フィールド内の改行文字は垂直タブ文字になる。
全てのフィールドは「"」で囲まれ、フィールド内の「"」は「""」になる。
5145:01/11/24 15:30
>>47
すまん。47を見てもう一度確認したところ、見た目には問題ないのだが、
セルの中でカーソルを動かすと、幅0の目に見えない文字(藁)が入っている。
てことで、45は撤回。セル内改行はExcel 2000でも0Aのみでないとダメ。
5247:01/11/24 17:42
>>51
了解。やはり2000でもマズかったようですね。
53仕様書無しさん:01/11/24 17:44
>>50
FileMakerの仕様は初耳。CSVってやっぱりいろいろ方言があるんだ...
54仕様書無しさん:01/11/24 20:33
55仕様書無しさん:01/11/24 21:34
>>54
これは、要素内の改行には対応してないみたいね。

俺も探してみよー。
56仕様書無しさん:01/11/24 21:55
>48 CSVの仕様ってのは存在しないんだよ。
だから、CSVのパーサを作る時一番大変なのは、CSVの仕様を決定すること。
当然Excelモードは欲しいから、Excelのファイル形式を洗い出すところから
始めなきゃならん。
57仕様書無しさん:01/11/24 22:36
>>56 が良いこと言った
58仕様書無しさん:01/11/25 00:07
CSVってエスケープシーケンスって無いの?
カンマとか引用符はどうするの?
59仕様書無しさん:01/11/25 00:16
>>58
実装者が決定するんじゃないの?
60仕様書無しさん:01/11/25 00:26
>>58
Excelだと、次のような感じ。
セル内にカンマや改行があれば、セルをダブルクォートで括る。
ダブルクォートで括ったセルにダブルクォートを入れたい場合は2個連続で1個
のダブルクォートとみなす。
エスケープシーケンスはExcelのCSVには多分ないと思う。

あとは >>59 が書いているように実装する者が決めることになるのだと
思う。セルがカンマ(と改行)でセパレートされてさえいたらとりあえず
CSVなんだし。
6158:01/11/25 00:32
因みに私は、\ エスケープを使用する形で実装する事が多いです。
62仕様書無しさん:01/11/25 00:56
仕様書にExcel互換とする。って書いてある。鬱
63仕様書無しさん:01/11/25 01:19
>>62
だったら、Excelでいろいろ書きまくってCSVで保存してみたら?
Excelだったら改行以外の制御コードは扱わないで良いと思うけど。
64仕様書無しさん:01/11/25 01:40
>>63
コーディングは終わったけど・・・
java でやることはきまってたのでストリームで読みながら、データの整合性を
チェックして・・・
きったないソースができた。解読不能
65仕様書無しさん:01/11/25 02:05
>>64
>>1 は C 言語限定っていってるけど (w
66仕様書無しさん:01/11/25 02:17
言語はなんでも、ExcelのCSVを解析するよいソースがあればいいなと思って
このスレをみてたのです。
Cでどうぞ
6756:01/11/25 02:51
Javaがいいなー。CSVTokenizer
6866:01/11/25 03:09
>>66
だけど、Excel互換ではないよね。互換だったらURLキボンヌ
6966:01/11/25 03:10
66は自分ジャン
>>67
70仕様書無しさん:01/11/25 07:27
プログラミング作法(Brian W.Kernighan・Rob Pike著)
に載っているCSV分析について調べているページ。
http://dontaku.csce.kyushu-u.ac.jp/~yoshi_w/study/b4seminar/0612/0612.html

公式サイトもあるがURL忘れた。

ハッカーが書いてもやっぱりこれくらいやらないと分析できないのか?
MSのCSV仕様がいかに行き当たりばったりかわかります。
71仕様書無しさん:01/11/25 07:35
公式サイト

The Practice of Programming
by Brian W. Kernighan and Rob Pike.
http://cm.bell-labs.com/cm/cs/tpop/

Code from The Practice of Programming
http://cm.bell-labs.com/cm/cs/tpop/code.html
CSV programs from Chapter 4 を見るべし。

日本語版¥2800円也。コストパフォーマンス極めて高し。
72仕様書無しさん:01/11/25 07:39
K&PがCSVを設計してたらこんな仕様には
しなかったと思うのが良く分かります。
¥でカンマやダブルコーテーションをエスケープしていれば
こんな心配事しなくても済んだのに・・・
73仕様書無しさん:01/11/25 09:22
でも¥マークってShift-JISの2バイト目と競合するから面倒だと思う。
74仕様書無しさん:01/11/25 12:54
>>73
ケツから解析しなければ問題ないんでねーの?
75仕様書無しさん:01/11/25 15:02
>>74
# とか $ だったらもっと簡単にならない? Shift-JISでもEUC-JPでも
共通でいけそうな気がするけど。
7674:01/11/25 15:23
>>75
それもいいかも。
でも『エスケープは \ だ』って思ってる向きには使いづらいかも。
7775:01/11/25 15:35
>>76
>でも『エスケープは \ だ』って思ってる向きには使いづらいかも。

確かに。
# とか $ でエスケープしたら「何それ?」って言われそう。

ただ、CGIなんかだと8ビット目が立っていたり、コントロールコード
だったりしたら、%(文字コード)で処理してるし、途方もない暴挙では
ないような気もする。
7874:01/11/25 15:45
>>77
いっそのことセル内は URL エンコードするってのはどうでしょ?
79仕様書無しさん:01/11/26 00:58
チャレンジしてみたが、90行超えた時点でエレガントはあきらめた。
yacc & lexつかった方がはえぇ。
"の""は文字とか改行継続とかリードバッファ分割とかがソースを汚くする。
バッファ分割しないで丸ごとってのも、1GのCSVファイル読むと使いものに
ならない、とかなりそうで嫌だしなぁ。
80仕様書無しさん:01/11/26 01:03
>>79
お疲れ様。
yacc & lex 使うと余計汚くなんない?
yacc や lex のソース自体があまり綺麗なものじゃないし...
811:01/11/26 01:35
二日過ぎたからきてみたが、なんだ誰もできねえのか
糞ばっかだな、ここ
82仕様書無しさん:01/11/26 01:40
宿題終わんなくて残念だね>1
83仕様書無しさん:01/11/26 02:12
Unix系の発想だとエスケープに「\」を使いたくなるけど、引用符中の引用符
のエスケープに引用符自体を連続して書くのはそれほどめずらしくもないような
気もする。
79でyacc、lexが出てるのを見て、一文字ずつ処理するオートマトンでなんと
かするってのを思いついた。きれいに実装できるかチャレンジしてみるか。
84仕様書無しさん:01/11/26 02:22
age
85null:01/11/26 02:30
そもそもCSVを解析するってのが意味が不明瞭だよな。
86仕様書無しさん:01/11/26 04:06
>>81-82
ワラタ。ここまで厨房まるだしの>>1は久々に見た。
そもそも宿題になるレベルかぁ?
・・・なってるんだろうなぁ。
8783:01/11/26 05:13
できた。(3時間かかったわけじゃないぞ。所要時間は20分くらいかな)
なんか全部ポストできないみたいだから、さわりだけ。

enum csv_result {
 CSV_CONTINUE, CSV_ERROR, CSV_END, CSV_FIELD, CSV_LAST_FIELD
};

typedef struct csv_struct csv_t;

struct csv_struct {
 enum csv_result (*parse)(csv_t *, int); /* 初期値はparse_plainにする */
 int (*in)(void *); /* (バッファ|ファイル)から1文字取ってくる。終端以降ではEOF */
 void *inp; /* inへ渡す引数 */
 int (*out)(void *, int); /* バッファへ1文字追加 */
 void *outp; /* outへ渡す引数 */
};

/* こいつらが中でcsv_struct.parseをうにうに変更する */
static enum csv_result parse_plain(csv_t *, int);
static enum csv_result parse_quote(csv_t *, int);
static enum csv_result parse_in_quote(csv_t *, int);
static enum csv_result parse_quote_in_quote(csv_t *, int);

enum csv_result
csv_reader(csv_t *csvp)
{
 int c;
 enum csv_result r;

 if (csvp->parse == NULL)
  return CSV_END;
 for (;;) {
  c = (csvp->in)(csvp->inp);
  r = (csvp->parse)(csvp, c);
  if (r != CSV_CONTINUE)
   return r;
 }
}
88仕様書無しさん:01/11/26 22:26
>>87
コードは全部で何行よ?
89仕様書無しさん:01/11/26 22:29
>>87
さわりがこれじゃ・・・(以下略)
90仕様書無しさん:01/11/27 01:16
>>1 じゃないけど
Excel の CSV
カンマで区切られた文字列を1要素とする。
基本的に改行を1レコードの区切りとする。
要素の中に[,]["][CR-LF]を含む場合
1.要素内の["]は[""]に変換する。
2.要素内の[CR-LF]は[LF]に変換する
3.["]で要素全体を挟む
でいいのかな?
めんどくさいね。
91仕様書無しさん:01/11/27 01:25
strtok っぽい形の CSV 解析関数が52行で書けたんだが、
これでは仕様が簡単過ぎるのか?
でも、わざわざ左右の空白のトリミングもしてるしなぁ。
92(゚д゚)ウマー:01/11/27 02:21
ソローリ。。
9383:01/11/27 05:49
>>88,89
csv_t使わないでcsv_reader内にstaticな変数を置き、でかいswitch文
使ってた時は50行くらいだったかな。ネストが深くなるし、FALLTHROUGH
使いまくりで汚かったからオートマトンは関数ポインタで実現することにし、
汎用的に使えるように色々改造してったらセットアップ部も含めて全部で
100行ちょいくらいになった。
他の言語だともっとスマートに書けるかな。
94仕様書無しさん:01/11/27 08:19
>>91
少なくともExcelだとセル内文字列の左右に空白がある場合でも""でくくりません。
だから数値データであることが明らかでない限りトリミングすると不都合があるよ。
95通りすがり:01/11/27 09:09
>>90
>要素の中に[,]["][CR-LF]を含む場合
>1.要素内の["]は[""]に変換する。
>2.要素内の[CR-LF]は[LF]に変換する
>3.["]で要素全体を挟む

補足が必要。入力の場合は
 赤",青,黄
は、
 「赤"」、「青」、「黄」
と解釈される。Excelでは。(Excel2000で確認)
また、出力のとき「赤"」がそのまま出力されるか
 「"赤"""」
と出力されるかどうかは、バージョンによる。
(いつから後者になったかは、よく分からない)

ちなみに、赤"はヴァカと読む。
96仕様書無しさん:01/11/27 10:29
>>95
>  「赤"」、「青」、「黄」
> と解釈される。Excelでは。(Excel2000で確認)
知らんかった。フィールドの最初の「"」以外はクオートの開始にはならないわけね。
97仕様書無しさん:01/11/27 11:34
> 「"赤"""」
>と出力されるかどうかは、バージョンによる。
これが困るんだよね。ゲイツ君
9891:01/11/27 12:56
>>94
っちゅーことは、もっと短くなるわけか。
9991:01/11/27 17:38
いろいろ改良した結果、C で 44 行、C++ で 38 行だ。
ただ、C の方はちと汎用性に欠けるコードだけど。
100仕様書無しさん:01/11/28 00:28
>>99
44 行ってすげー。まじで荒らしとかじゃなくて見てみたい。>コード

100!!
10191:01/11/28 12:51
>>100
1 の書き込みから少なくとも一週間経ってから。:P

enum とかプロトタイプとか含めるともうちょい行数増えるけどね。
あと、strtok と似たような仕様で、
純粋に切り出すところの処理しか書いてない。
それと、Excel の仕様と合致してないところが少し...。
でも、Excel の仕様同士がそもそも合致してない!

C は入出力の両方とも文字列として書いてるので汎用性低い。
83 さんのように汎用的にすると、
読み出し書き込み処理も書く必要があって、
C ではどうしても長くなってしまう。
そこをさぼってるから 44 行に収まるのであって、
まともに作ると全体ではかなり長くなってしまう。
C++ だとそのあたり istream や string/ostream が使えて、
気軽に汎用的にすることができる。
102仕様書無しさん:01/11/28 23:06
perl5のライブラリにCSVを解釈するものがあるようなんですが
103仕様書無しさん:01/11/28 23:13
ODBCのテキストドライバーをCから使うってのが正解じゃないか?<お前ら
104仕様書無しさん:01/11/30 20:52
プログラマとしての力量が問われるスレだろ?
腕に自信が有るプログラマなら討論すべし。
105仕様書無しさん:01/11/30 22:14
CVSを解析して、漢字コード混在の問題をどーにかしてください。
10691:01/12/01 03:58
typedef enum _tag_csv_ret_t
{
 CSV_TOKEN, CSV_EOL, CSV_END,
} csv_ret_t;

csv_ret_t csvtok(char** pstart, char* buffer, int bufsize)
{
 int i, ibuf = 0;
 char letter;
 char* start = *pstart;

 if(start[0] == '\0')
  return CSV_END;

 for(i = 0; ; i++)
 {
  letter = start[i];
  switch(letter)
  {
  case ',':
   if(start[i + 1] == '\n' || start[i + 1] == '\0')
    letter = start[++i];
  case '\0':
  case '\n':
   goto MAIN_LOOP_OUT;

  case '"':
   for(i++; letter = start[i], letter != '\0'; i++)
   {
    if(letter == '"')
    {
     if(start[i + 1] != '"')
      break;
     i++;
    }
    if(ibuf < bufsize - 1)
     buffer[ibuf++] = letter;
   }
   break;

  default:
   if(ibuf < bufsize - 1)
    buffer[ibuf++] = letter;
   break;
  }
 }
MAIN_LOOP_OUT:

 buffer[ibuf] = '\0';
 *pstart = &start[i + 1];
 return (letter == '\n' || letter == '\0' ? CSV_EOL : CSV_TOKEN);
}
107C++ ver:01/12/01 04:17
template <typename char_type>
csv_ret_t csvtok(istream& src, basic_string<char_type>& dst)
{
 dst.erase();

 int letter = src.get();
 // char_type へのキャストでは危険? でも、L 使うとテンプレートにできないし。
 if(letter == (char_type)(unsigned char)('\0') || letter == char_traits<char_type>::eof())
  return CSV_END;

 for(; !src.eof(); letter = src.get())
 {
  switch(letter)
  {
  case (char_type)(unsigned char)(','):
   letter = src.peek();
   if( ! (letter == (char_type)(unsigned char)('\n') || letter == char_traits<char_type>::eof()) )
    return CSV_TOKEN;
   src.get();
  case (char_type)(unsigned char)('\n'):
   return CSV_EOL;

  case (char_type)(unsigned char)('"'):
   for(letter = src.get(); !src.eof(); letter = src.get())
   {
    if(letter == (char_type)(unsigned char)('"'))
    {
     if(src.peek() != (char_type)(unsigned char)('"'))
      break;
     src.get();
    }
    dst += letter;
   }
   break;

  default:
   dst += letter;
   break;
  }
 }
 return CSV_EOL;
}
10879:01/12/01 11:32
負けたかも。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CleanUpErrorReturn(buf) { free(buf); return( NULL ); }

#define CopyDataWithFree(Dest, Src) { \
strcpy(Dest, Src); free(Src); Src = NULL; \
}

#define SetDataWithXchgPointer(Buf, Mst, c, len) { \
CopyDataWithFree(Buf, Mst); \
Buf[len-2] = c; Buf[len-1] = '\0'; Mst = Buf; \
}

char *GetWord(FILE *fp)
{
size_t len;
static char c, c2, *pcWord, *pcLocalBuf;

len = 0;

if( (pcWord = (char *)malloc(++len)) == NULL ) return( NULL );
pcWord[0] = '\0';

if( (c = fgetc(fp)) == EOF ) CleanUpErrorReturn(pcWord);
10979:01/12/01 11:33
switch( c ) {
case '"': /* Quote */
while( (c = fgetc(fp)) != EOF ) {
if( (pcLocalBuf = (char *)malloc(++len)) == NULL ) {
fprintf(stderr, "\n[%d] malloc()\n", __LINE__);
CleanUpErrorReturn(pcWord);
}
switch( c ) {
case '"': /* "" Check */
switch( (c2 = fgetc(fp)) ) {
case '"':
SetDataWithXchgPointer(pcLocalBuf, pcWord, c, l

break;
case EOF:
default:
fgetc(fp); // Trim ','
CopyDataWithFree(pcLocalBuf, pcWord);
return( pcLocalBuf );
}
break;
default:
SetDataWithXchgPointer(pcLocalBuf, pcWord, c, len);
}
}
11079:01/12/01 11:35
default: /* Not Quote */
do {
if( (pcLocalBuf = (char *)malloc(++len)) == NULL ) {
fprintf(stderr, "\n[%d] malloc()\n", __LINE__);
CleanUpErrorReturn(pcWord);
}
switch( c ) {
case '\r':
fgetc(fp); // Trim '\n'
case ',':
CopyDataWithFree(pcLocalBuf, pcWord);
return( pcLocalBuf );
default:
SetDataWithXchgPointer(pcLocalBuf, pcWord, c, len);
}
} while( (c = fgetc(fp)) != EOF );
}

return( pcWord );
}
11179:01/12/01 11:36
int main(int argc, char **argv)
{
char *pc;
FILE *fp;

if( argc > 1 ) {
if( (fp = fopen(argv[1], "r")) == NULL ) {
perror("fopen");
exit(1);
}
}
else
fp = stdin;

while( (pc = GetWord(fp)) != NULL ) {
printf("[WORD] <%s>\n", pc);
free(pc);
}

if( fp != stdin )
fclose(fp);

return( 0 );
}
112109:01/12/01 11:43
訂正.
case '"': /* "" Check */
switch( (c2 = fgetc(fp)) ) {
case '"':
SetDataWithXchgPointer(pcLocalBuf, pcWord, c, len); ←かけちやた
break;
113仕様書無しさん:01/12/01 20:03
↑こんなコード書いているようじゃいつまで経っても二流だな。
11479:01/12/01 21:00
>>113
ごめそ。それにバグってた(藁。
fgetc(fp); // Trim ',' の行いらない。

申し訳ないのでしばらく書き込み自粛するね。
115仕様書無しさん:01/12/04 22:07
>>114
めげずに投稿しろよ!間違っててもいい。
それについての批判はプラス指向にとらえればいい。
そこまでの発想力があるならもったいない。
116仕様書無しさん:01/12/15 03:02
このスレみるとExcel互換のCSV解析が要求されることが多い
ってことだけど、それ、目標を間違えてないか?
Excelの*.csvって、基本的にExcel独自の保存形式の1つだよ。
だから、"007"を文字列「007」じゃなく数値「7」って解釈して
平気でいたりする。
でも、ほとんどのアプリケーションは"007"は文字列「007」って
解釈して欲しいんじゃないか?
Accsess互換のほうがまだましな気がする。
117Kusakabe Youichi:01/12/15 03:07
In article >>116, 仕様書無しさん/116 wrote:
> Excelの*.csvって、基本的にExcel独自の保存形式の1つだよ。

でもExcel以前からありまたよ:)
118仕様書無しさん:01/12/15 03:13
>でもExcel以前からありまたよ:)

ププッ(W
119Kusakabe Youichi:01/12/15 03:17
In article >>118, 仕様書無しさん/sage/118 wrote:

> >でもExcel以前からありまたよ:)
>
> ププッ(W

「とりあえず何か言っておく」なんてのができるのも匿名ならではですか? :)
120仕様書無しさん:01/12/15 03:19
ププのプ(W
121116:01/12/15 03:43
>>117

だからあ、「Excelの*.csv」っていってるじゃん!
それ以前からあったK3などとは別の話。
122Kusakabe Youichi:01/12/15 03:49
In article >>121, 116/121 wrote:
> だからあ、「Excelの*.csv」っていってるじゃん!

そうじゃなくてcsvはExcel以前からあったよと言っているだけですよ?
123仕様書無しさん:01/12/15 03:50
>>122

だから、、「Excelの*.csv」って、特定してるんでしょ、>>121は。
アフォですか?
124仕様書無しさん:01/12/15 03:51
>>123

アフォに決まってるじゃないか。お前はアフォか。
125仕様書無しさん:01/12/15 03:53
先生はExcelについてあまり詳しくないので
許してあげてください。
126仕様書無しさん:01/12/15 03:56
先生はロータスなら少しつかえます。
127Kusakabe Youichi:01/12/15 03:59
In article >>123, 仕様書無しさん/123 wrote:
> だから、、「Excelの*.csv」って、特定してるんでしょ

いいえ、わたしはしてませんよ。
128仕様書無しさん:01/12/15 04:02
先生は話の流れが理解できないので許してあげて
ください。
129仕様書無しさん:01/12/15 04:03
あぁ、いつから.docと付くファイルがプレーンなテキストで書かれたドキュメントファイルじゃ無くなったんだろう。

CSV使うくらいなら、<TABLE></TABLE>使ってやるぅ!!
130Kusakabe Youichi:01/12/15 04:03
In article >>125, 仕様書無しさん/sage/125 wrote:

> 先生はExcelについてあまり詳しくないので
> 許してあげてください。

とか言っているやつはイースターエッグを見つけられなかったやつだとみた:)
131Kusakabe Youichi:01/12/15 04:04
In article >>126, 仕様書無しさん/sage/126 wrote:

> 先生はロータスなら少しつかえます。

そんなもんつかってどうする:)
132Kusakabe Youichi:01/12/15 04:05
In article >>128, 仕様書無しさん/sage/128 wrote:

> 先生は話の流れが理解できないので

理解できていないのはあなたでしょうね。
133Kusakabe Youichi:01/12/15 04:05
In article >>129, 仕様書無しさん/sage/129 wrote:

> あぁ、いつから.docと付くファイルがプレーンなテキストで書かれたドキュメントファイルじゃ無くなったんだろう。

MS-Wordがでてきたころからdしょうね。
134仕様書無しさん:01/12/15 04:06
>>133

dしょうね とは?
135仕様書無しさん:01/12/15 04:07
困ったとき誤魔化すのは先生の得意技なので
許してあげてください。
136仕様書無しさん:01/12/15 04:07
先生は感情が高ぶると手が震えてキーがまともに打てなくなるので許してあげてください。
137116:01/12/15 04:09
>128

これがクサカベたんなのか。。。
やはり、初めから無視すべきだったのか。。。
138Kusakabe Youichi:01/12/15 04:09
In article >>135, 仕様書無しさん/sage/135 wrote:

> 困ったとき誤魔化すのは先生の得意技なので

ということにしたいのですね? :)
139K子 :01/12/15 04:09
先生はボケっていらっしゃいます。
少しの事は大目にみてください。
140Kusakabe Youichi:01/12/15 04:09
In article >>136, 仕様書無しさん/136 wrote:

> 先生は感情が高ぶると手が震えてキーがまともに打てなくなるので

そう思うと安心できるのですか? :)

# あいにく誤植はしょっちゅうですが。
141仕様書無しさん:01/12/15 04:12
すぐに「ということにしたいのですね? :) 」と書いて
しまうのは他に書くことが無くなったときなので、それ以上
先生を追い詰めるのはやめてあげてください。
142Kusakabe Youichi:01/12/15 04:16
In article >>141, 仕様書無しさん/sage/141 wrote:

> すぐに「ということにしたいのですね? :) 」と書いて

すぐにって、速度は関係ないですね。
頻度については、「そんな反応されるような、ごまかし'感想'」を
補足しているだけなので、それが出てくる頻度にすぎないですね。

> しまうのは他に書くことが無くなったときなので、

と思いたいわけですね? :)
143仕様書無しさん:01/12/15 04:16
>>137
日下部も必死なんだよ。
奴の日常会話を見てみろ↓



「日下部」ちくしょう!ちくしょう!
「けいこ」あなた、また2chを荒らしているのね?
「日下部」うるさい、お前は黙ってろ!
「けいこ」あなたの、あなたのせいで、私や娘に身の危険が迫っているのよ!
「日下部」2chの奴らのせいで私の本が売れなくなったのだぞ!
「けいこ」だからって自分の本を何百冊も買わなくても・・・
「日下部」黙れ、黙れ!
144仕様書無しさん:01/12/15 04:56
ワラタ
145仕様書無しさん:01/12/15 07:35

                  /  ̄ ̄ ̄ ̄\
                 /          ヽ
                 /           ヽ
                 | 人_____________     |
                 |●  ●  |     |  クソスレもほどほどにね
                 /       /   / |
                /|▼     ./  /  |
     ____________     |___|┴―   /__/ |  丿
     \〜〜 /       |  ̄        |__/ )
      \ /___       (\___    /  )―――
      ( つ(__/ \      (  |   /   )
      (__フ|    \  / (  |  /    )
      ⊂―||―、   | /
146仕様書無しさん:01/12/15 09:01
もう何が何やら。
147Kusakabe Youichi:01/12/15 09:56
In article >>146, 仕様書無しさん/sage/146 wrote:

> もう何が何やら。

ってのは、「何かケチつけてみたいけど具体的なことは何も言えないので
とりあえず何か言ってみる」テストですか? :)
148K子 :01/12/15 10:25
あなた、もうやめてください。
149まにあ:01/12/15 11:00
毎日のように日下部先生の書きこみを見てオナニーをしています。
150:01/12/15 11:49
お父さん。
みっともないからやめて。
151ふつーATOK:01/12/15 11:51
>>147
>In article >>146, 仕様書無しさん/sage/146 wrote:
>
>> もう何が何やら。
>ってのは、「何かケチつけてみたいけど具体的なことは何も言えないので
>とりあえず何か言ってみる」テストですか? :)

これと同じですね。
「はつみみです」
「と思いたいわけですね」
「もう思考停止ですか」
「ということにしたいのですね」
「そう思うと安心できるのですか」
「こわがらなくてもいいのにー」
152仕様書無しさん:01/12/15 12:49
perlでDBD::CSVがおすすめ。
153仕様書無しさん:01/12/15 14:29
ごしょく 【誤植】



ごしょく 0 【誤植】

--------------------------------------------------------------------------------

印刷物で、文字・記号などに誤りのあること。ミス-プリント。


154仕様書無しさん:01/12/15 16:17
>153
ワラタ
日下部脳内辞書にはなんと書いてあるか見てみたい(藁
155仕様書無しさん:01/12/15 17:24
CSV解析で、注意する点はなんでしょうか?
156仕様書無しさん:01/12/15 18:43
>>155
今時のエクセル
 1,2,3,4,5,,,\n
 a,b,c,d,e,f,g,h\n
古いエクセル
 1,2,3,4,5\n
 a,b,c,d,e,f,g,h\n

この違いに注意して解析してみてください。

「CSV編集ソフト」と冠するもののなかでもこういった
テキストを吐き出すものが稀に存在します。
読み込みに失敗した場合にはまずカンマ(要は区切り記号ね)
の数を疑ってみてください。
157仕様書無しさん:01/12/15 19:12
はぁ…
やっと臭蚊屁が帰りましたねぇ。ソンナニ コワガラナクテモ イイノニ
「全く」臭蚊屁ってなんで話の流れが読めないんだろう? ト イウコトニ シタイノデス
そもそも、彼の辞書には「全く」は「全く」との読みでは載っていないらしい
ハツミミデス。
158仕様書無しさん:01/12/15 19:14
> > もう何が何やら。
> ってのは、「何かケチつけてみたいけど具体的なことは何も言えないので
> とりあえず何か言ってみる」テストですか? :)

生々しい日下部の屁理屈ではそうかもしれないが、
生々しい日下部以外の人には意味が通じている。十分でしょ。
159仕様書無しさん:01/12/15 19:16
なんか臭蚊屁のおかげでスレ住人の結束力が高まっているような気がする。

臭蚊屁には感謝....スルワケネエェ
160Kusakabe Youichi:01/12/15 19:18
In article >>158, 仕様書無しさん/sage/158 wrote:

> > > もう何が何やら。
> > ってのは、「何かケチつけてみたいけど具体的なことは何も言えないので
> > とりあえず何か言ってみる」テストですか? :)
>
屁理屈ではそうかもしれないが、

屁理屈だということにしたいのですか? :)
161仕様書無しさん:01/12/15 19:22
つーか屁だ。おまえは。
162仕様書無しさん:01/12/15 19:26
> > 生々しい日下部の屁理屈ではそうかもしれないが、
> > 生々しい日下部以外の人には意味が通じている。十分でしょ。
> 屁理屈だということにしたいのですか? :)

ほのかに臭う日下部はだらしないねぇ。正しい引用も出来なくなってきたの?
163仕様書無しさん:01/12/15 19:32
ハンカクカナハ ヨメルヨウニ ナッタノ?
164仕様書無しさん:01/12/15 20:23

みんな気をつけろ!スレ違いの話題に流されるな!
165仕様書無しさん:01/12/15 20:54
>>116
007の話は頷ける。
Excel97なのだけど
(1)007 って打ったら セル上で 7。 CSV で 7。このCSVをExcelで再読み込みしたら 7。
(2)'007 って打ったら セル上で 007。CSV で 007。このCSVをExcelで再読み込みしたら 7。
(3)CSVのテキストで '007 って入れておいてExcelで読み込んだら '007 って「'」が付く。
(4)CSVのテキストで "007" って入れておいてExcelで読み込んだら 7 になる。

CSVからの読み込みで 007 にする方法があったら教えてくれー。
「Accsess互換」っていうのもちょっと気になるよ。

ちなみにロータス123 2001 だと、(4)のケースは 007 と認識してくれる。
166仕様書無しさん:01/12/15 20:57
>>165
ダブルクォートでくくる
167165:01/12/15 20:58
あ、念のため。
俺は「ExcelのCSVを解析する」という前提で話が進むことは、それで良いと思ってる。
仕様の良し悪しは全く別の話。
「ExcelのCSVを解析する」ことが要求されることは実際多いし。
168165:01/12/15 21:01
>>166
>ダブルクォートでくくる
せっかくレスくれたけど、>>165 の(4)の通り。
Excel97は"007"とCSVに書いておいても、読み込んだら「7」になってしまう。
Excel2000や2002あたりでは変わっている?
169166:01/12/15 21:01
ごめん、execl2000だとだめだった

どうやるんだろう
170165:01/12/15 21:03
>>166
あ、それってAccessの話?
171165:01/12/15 21:04
>>169
すんません。>170が かぶっちゃった。
172166:01/12/15 21:26
いやスマン、遙か昔の知識。当てずっぽうだった(w

いまEXCEL2000で確かめてみたが
"007"→'007
'007'→'007'
""007→7(なんだこの変換は?)
\007→\007
\"007\"→\"007\"
\'007\'→\'007\'

ダブルクォートでくくると、中のカンマを文字列の一部としてみてくれるらしい
"007,00"→007,00
173166
訂正
"007"→7だな