QA@IT
この質問・回答は、@ITの旧掲示板からインポートされたものです。

【C#】EOFの文字コード(制御文字?)ってありますか?

いつも勉強させて頂いてます。

現在、C#にてテキストファイル(CSV)の読み込みを行っているのですが
ReadLineメソッドを使用して一行分を読んで配列にセットし、後で一文字づつ
カンマでばらして項目取得する…という方法を取っています。

この場合に、最後の行のCRLFの後にEOF(コード?0x1Aです)があると
空の行が出来てしまいます。 最後に取得したものがEOFコード?かどうかを判別
し、EOFであれば無視する といった事が行いたいのですが、この「EOFか」
というのはどうやって判別するものなのでしょうか?

例えば、改行なら「\r\n」等がありますが、それと同じ様な表記というかコードは
無いものでしょうか? かなりネットで色々調べてはいるのですが見当たらなく、
C#のデバッグで見ると、EOFは「・」になっていたので、「・」かどうか?
という記述で凌いでいます。。 が、どうも邪道の様な気がしまして。

そういった簡単に判別するコードがあるのかどうか、というのをご教授願えない
でしょうか? どうぞよろしくお願い致します。

質問者:Sala

回答

こんにちは。

EOFコードかどうか、という意味であれば 0x1a で調べられると思います。
たとえば、取得した文字列を Trim メソッドで

 line.Trim(' ', '\t', '\x1a');

という感じで空白などのゴミを取り除いた後で、空文字列かどうか比較すれ
ばスマートに行くのではないでしょうか。

また、CSV の話であれば以下のスレッドも役に立つと思います。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=32134&forum=7
_________________ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。

投稿者:ぽぴ王子

編集 履歴 (0)

こんにちは。

ReadLineのメソッドを使用している場合、
末尾に到達した場合にNullを返します。

また、scv形式で取得しているようですが、
特定のフォーマットに合っていない(取得した数が違うとか)
で判断してもいいのではないでしょうか?

後で一文字づつ カンマでばらして
この方法ではなく、
String.Splitがいいかと思います。

投稿者:カルガモ

編集 履歴 (0)

さっそくのご返答、ありがとうございます。

>ぽぴ王子様
 ありがとうございます!!
 質問の意図は「EOF="\x1a"」これが知りたかったんです!
 もしかして、16進コードの一文字目を「¥」にしたら他の文字
 もそういう書き方が出来るのでしょうか。。
 (例えば「\n」は「\x0a」でも一緒でしょうか・・)
 おかげ様で解決しました。ありがとうございます。
 
 教えて頂いたリンク…かなり参考になりました。
 (読んでいたので返信が遅れてすみません)
 CSVのやり取りにはよく受信側で泣かされるので、受け側
 がしっかり確認しないといけないですよね。。
 (VBでは慣れていたのですが、C#だとまだ勝手が分からなくて)
 パッケージソフトの標準取込機能なので、どこまで対応させておく
 べきか…また熟考しないといけないなと思いました。
 
 まずはありがとうございました!

>カルガモ様
 Splitにしようと思ったのですが、ダブルコーテーションの扱いや
 システム上変換かけないといけない文字(シングルコーテーションとか)
 等もあったので、Splitを使わずに一文字ずつチェックする方式で考えて
 おりました。 Split使えれば楽なんでしょうけど。。
 簡単にするか、どの例外的な部分まで考慮するかが難しいですね。。
 
 

投稿者:Sala

編集 履歴 (0)

EOF(0x1A)は現在ファイル終端子としては使われてません。
そもそもEOF自体が8bit世代の計算機との互換性の為に残されていたものです。
なので、現在のシステムでEOFをファイルの最後に付けることはありません。
レガシーシステムとの連携やマイグレーションを行っているとたまに出てきます。

CSVの出力元がレガシーなシステムであれば、ファイルの最後にEOFが付与されて
来る場合がありますが、そのような場合でもEOFは削除して処理した方が良いと思
います。現在のシステムがEOFを付けないのですから、後々のことを考えても、EOF
抜きで処理するようにしておいた方が良いと思います。

CSVに関してはRFCで標準が定義されたみたい(前スレ参照?)ですので、そちらを
参照してみては如何でしょうか?

投稿者:がんふぃーるど

編集 履歴 (0)

こんにちは。

EOF に関する話はがんふぃーるどさんの書かれているとおりで、その辺は「た
ぶんそういう古いデータなのだろうなぁ」と思ってあえてスルーさせていただ
きました(質問とも直接関係なさそうでしたし)。
# 8bit というよりは MS-DOS 時代(いや、CP/M か?)のなごりじゃないか
# という話はさておき。

で、一文字ずつ読み進めていく方法はあながち悪い方法でもないのですが、
それには ReadLine で読み込んでいてはあまり意味がない(途中で改行さ
れている場合に対応できない)ようにも思えますし、逆にそこまで気合の入っ
た作りにする必要はあるのか、とか少し考えてしまいますね。
件のスレッドのように、途中で改行されたりダブルクォーテーションで区切ら
れた中にカンマがありますよ的なファイルであればともかく、そうではないと
明確に定義できるのであれば、簡単に ReadLine と Split でお手軽に済
ませるのもアリかと思います。

ただ、パッケージソフトの標準取込機能とのことですので、どのようなファイ
ルを受け取るかわからないという点で熟考すべきところではあると思います
が、そうなると ReadLine じゃ途中改行が以下略。

ラジオ福島…もとい RFC に関しては「必ずそれに従わなくてはならない」と
いうわけではないので、とりあえず参考程度に見ておくのはいいと思います。
その上で「うちのパッケージは途中改行なんて認めねえんだよ!」とか仕様
に書いて販売するというごくあくひど…じゃない英断も可能かと。
_________________ぽぴ王子@わんくま同盟
ぽぴ王子の人生プログラミング中 / ぽぴンち。

投稿者:ぽぴ王子

編集 履歴 (0)

前回のご回答で解決しましたので、その後見ていなかったら…追記頂いてたんですね。
大変遅くなりまして失礼しました。

>がんふぃーるど様
 現在取り扱っている実データでEOFが居るのです…(苦笑)
 取込ファイルを作るシステムは別会社が作ってますが、Win2000やXPで動いている
 システムなんですけどね。。(大手会社の送受信システムですが。。)
 そこが吐き出してくれるCSVにちゃっかり付いてまして。
 これって、CSV吐き出し側がわざわざ付けてくれてるって事なんですかね…。。

 付いてなければ問題ない、あった時に余計なデータが出来て困るので
 「もしもEOFが入っていたら…」っていう処理をする為に探しておりました。
 基本、古き時代のものなんですね。覚えておきます。ありがとうございました。

>ぽぴ王子様
 難しい所です。。。 パッケージと言っても、箱に入れて電気屋で売っている
 物ではないので、あんまり例外的なものが出て来たらカスタマ対応になるのですが
 それを減らす為に、どこまでやっておくか…というのが困りものです。。
 今までの実績から行くと、まだ途中で改行される嫌なデータは出会った事は無いの
 ですが、「’」とかはあるんですよね。(後でDBに漬け込むので、下手にシングル
 があるとSQL文で落っこちるので…これだけは少なくても処理したい。とか)
 まぁ置換で一気に変えちゃった後にSplitでも良いかも…とも思うのですが、後々
 もっと嫌なものが出てきたり、「"123,456"」とかが出てきた時に、一字読みの方が
 手直しするのは少しで済むだろう… という思いから、将来拡張しやすいように
 しているといった感じです。
 
 確かに個人的にはSplitで一気に分割の方が早いし楽で好きなんですけど。。

 結局、今の所途中改行や中カンマは保留にしておいて、実際にそんなデータに
 出くわした時点で機能強化しようかと思っています。

 色々勉強になりました。

 どうもありがとうございました! 
 
 
 
 

投稿者:Sala

編集 履歴 (0)

本題とは直接関係ないのですが、ちょっと気になったので・・・

Salaさんの書き込み (2006-07-31 10:58) より:

 まぁ置換で一気に変えちゃった後にSplitでも良いかも…とも思うのですが、後々

 もっと嫌なものが出てきたり、「"123,456"」とかが出てきた時に、一字読みの方が

 手直しするのは少しで済むだろう… という思いから、将来拡張しやすいように

 しているといった感じです。
Salaさんの件に関しては、詳細はわからないので、当てはまるかどうかはわかりませんが・・・

よく将来拡張しやすいように、今のうちに一番早いやり方を・・・とか、拡張性の高いものを・・・などというお話をよく見かけるのですが、これはケースバイケースだと思うのです。

利用されるデータがある程度予測のつくものであれば、その時点で必要なものに留める(ぽぴ王子さん(様?)の言うように、簡単にsplit で済ませることができるならそうするなど)のも大切なことだと思います。

むしろ大切なのは、必要になった時に「その部分」を差し替えられる様に常に意識して作ることではないでしょうか。

投稿者:R・田中一郎

編集 履歴 (0)
ウォッチ

この質問への回答やコメントをメールでお知らせします。