C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[9]: UTF-8(BOM無し)のCSVファイルを読み書き


(過去ログ 172 を表示中)

[トピック内 14 記事 (1 - 14 表示)]  << 0 >>

■98901 / inTopicNo.1)  UTF-8(BOM無し)のCSVファイルを読み書き
  
□投稿者/ ゆい (47回)-(2022/01/17(Mon) 17:59:19)

分類:[VB.NET/VB2005 以降] 

VB2017です。
お世話になります。

Using sr As New System.IO.StreamWriter(<ファイル名>, False) 
    sr.WriteLine("abc")

このようにしUTF-8(BOM無し)での書き込みをしています。
それを普通に読み込みもし、その中のデータの修正もした後に
もう一度UTF-8(BOM無し)での書き込みもすれば何か問題でもあるのでしょうか?

UTF-8(BOM無し)特有での読み込みの仕方は知りません。

引用返信 編集キー/
■98902 / inTopicNo.2)  Re[1]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ WebSurfer (2407回)-(2022/01/17(Mon) 18:26:31)
No98901 (ゆい さん) に返信
> VB2017です。

> もう一度UTF-8(BOM無し)での書き込みもすれば何か問題でもあるのでしょうか?

それは回答者側のセリフ・・・というか、あなたにとっての問題は何なのですか?

引用返信 編集キー/
■98903 / inTopicNo.3)  Re[1]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ 魔界の仮面弁士 (3278回)-(2022/01/17(Mon) 18:33:16)
2022/01/17(Mon) 20:42:18 編集(投稿者)

No98901 (ゆい さん) に返信
> このようにしUTF-8(BOM無し)での書き込みをしています。
> それを普通に読み込みもし、その中のデータの修正もした後に

StreamWriter は書き込みのための物で、読み込みはできませんよ?

ここでいう修正とは、具体的には、どのような操作を想定しているのでしょうか。
自作プログラム以外からの編集、たとえばユーザーによるメモ帳やVSCodeでの修正などでしょうか?


> もう一度UTF-8(BOM無し)での書き込みもすれば何か問題でもあるのでしょうか?
UTF-8 を使うべきかどうか、そして BOM を付与すべきかどうかは、
そもそも「書き込んだデータを読み込む側」の都合に合わせるべきです。

あるいは、保存データが BOM 無しを前提としているのであれば、
ファイルを読み込む側もそれを前提にした処理になるべきでしょう。

そのルールを守れば問題無いですし、ルールを破れば問題になりえる。ただそれだけかと。


もしも不安な場合は、Encoding クラスを使って、BOM の有無を自分で明示することもできます。
たとえば読み込み時には BOM の有無を自動判定させるようにして、
書き込み時には常に BOM 無しとして出力するという方針で実装してみるのは如何でしょう?

https://smdn.jp/programming/netfx/tips/unicode_encoding_bom/


> UTF-8(BOM無し)特有での読み込みの仕方は知りません。
StreamWriter であれ StreamReader であれ、エンコーディングを固定したいのであれば、
Encoding クラスを明示した方が、後から見た時に分かりやすいかと思います。

---

BOM(Byte Order Mark)とは本来、UTF-16 や UTF-32 のためのもので、
ファイルの先頭にリトルエンディアンかビッグエンディアンかを識別する、
U+FEFF という文字データを埋め込む仕組みです。

UTF-16(ビッグエンディアン)なら 2 バイトの FE,FF
UTF-16(リトルエンディアン)なら 2 バイトの FF,FE

UTF-8 の場合は、エンディアンを気にする必要が無いので本来は不要なのですが、
付与する場合は、U+FEFF に相当する 3 バイトの EF,BB,BF が付きます。
引用返信 編集キー/
■98904 / inTopicNo.4)  Re[2]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (48回)-(2022/01/17(Mon) 21:49:32)
No98903 (魔界の仮面弁士 さん) に返信

> そもそも「書き込んだデータを読み込む側」の都合に合わせるべきです。

そうなんですよね、データの引き渡しはUTF-8(BOM無し)でのCSVファイルともなっているのです。
Pythonとの関係もあるのかも知れません。
ただ確実のそのせいなのかはまだ分かってませんが、
ちなみにエラーメッセとしては「ValueError: could not convert string to float:」ともなっています。

すみません、また取り留めないこと言ってます。
もっとよく調べてもみることにします。



引用返信 編集キー/
■98905 / inTopicNo.5)  Re[2]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (49回)-(2022/01/17(Mon) 21:51:39)
No98902 (WebSurfer さん) に返信

>>もう一度UTF-8(BOM無し)での書き込みもすれば何か問題でもあるのでしょうか?
>
> それは回答者側のセリフ・・・というか、あなたにとっての問題は何なのですか?
>

確かにそうですね。
すみません。

引用返信 編集キー/
■98906 / inTopicNo.6)  Re[3]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ 魔界の仮面弁士 (3279回)-(2022/01/18(Tue) 01:05:59)
No98904 (ゆい さん) に返信
> ちなみにエラーメッセとしては「ValueError: could not convert string to float:」ともなっています。

「float(浮動小数点数)型に変換できない文字列」だと言っていますね。
どういうデータを渡したのですか?
引用返信 編集キー/
■98907 / inTopicNo.7)  Re[3]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ WebSurfer (2408回)-(2022/01/18(Tue) 09:50:51)
No98905 (ゆい さん) に返信
> ■No98902 (WebSurfer さん) に返信
>
> >>もう一度UTF-8(BOM無し)での書き込みもすれば何か問題でもあるのでしょうか?
>>
>>それは回答者側のセリフ・・・というか、あなたにとっての問題は何なのですか?
> >
>
> 確かにそうですね。

参考になるので一読することをお勧めします。

質問するときのヒント
https://teratail.com/help/question-tips

特に ↓ このあたり

"人に質問をするには、自分が何を尋ねたいかを知っている必要があります。これは、「自分が
今『何がわからないのか』がわかっていて、言語化できている」ということです。一見簡単なよ
うですが、実はとても難しいことです。何がわからないかわからない人から質問を受けても、
答える側も困ってしまいます。"

引用返信 編集キー/
■98913 / inTopicNo.8)  Re[4]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (50回)-(2022/01/19(Wed) 00:23:31)
No98906 (魔界の仮面弁士 さん) に返信

ありがとうございます。

> 「float(浮動小数点数)型に変換できない文字列」だと言っていますね。
そうなんですよね。
なので、未知に近いUTF-8(BOM無し)に、てっきり起因があるのでは? とも思ってもしまったのです。

実際は同じタイミングで修正採用もした、先日教えてもいただいた「WriteLine → Write」での、
そのままでは改行がされないがため、安直にも「sr.WriteLine()」が為にも関わらず。

今回もありがとうございました。
これに懲りずまたお願いします。



解決済み
引用返信 編集キー/
■98914 / inTopicNo.9)  Re[4]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (51回)-(2022/01/19(Wed) 00:30:32)
No98907 (WebSurfer さん) に返信

> 何がわからないかわからない人から質問を受けても、
> 答える側も困ってしまいます。"

ですね、分かってるのですよ。
でもこれがなかなか書けなくて。



解決済み
引用返信 編集キー/
■98917 / inTopicNo.10)  Re[5]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ WebSurfer (2410回)-(2022/01/19(Wed) 09:42:51)
No98914 (ゆい さん) に返信

> ですね、分かってるのですよ。
> でもこれがなかなか書けなくて。

厳しいことを言いますが、もしホントに分かっているならやるべきことをやってないのでは
ないですか?

情報の小出し・後出しはこういう Q&A サイトでは最も嫌われることの一つです。

エラーメッセージは、

ValueError: could not convert string to float:

だそうですが、後出ししないで一番最初の質問で書きましょう。それから、float: の
後に変換しようとした文字列があるのではないですか? であれば、それも書きましょう。

そしてもう一つ、質問する前にエラーメッセージでググってみましょう。役に立ちそう
な情報が多々ヒットするはずです。

上に紹介した「質問するときのヒント」の「1-2. 投稿前に検索し、できるところまで
自分でやってみましょう」も読んでください。

次回質問する際はよろしくお願いします。
引用返信 編集キー/
■98918 / inTopicNo.11)  Re[6]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ 魔界の仮面弁士 (3280回)-(2022/01/19(Wed) 10:40:29)
No98917 (WebSurfer さん) に返信
> エラーメッセージは、
> ValueError: could not convert string to float:
> だそうですが、後出ししないで一番最初の質問で書きましょう。それから、float: の
> 後に変換しようとした文字列があるのではないですか?


あるいは、本来は数値を出力しなければならない場所に、
実際には何も出力されていない(空文字列)とか…ですかね。



■98913 (ゆい さん) に返信
> 未知に近いUTF-8(BOM無し)に、てっきり起因があるのでは? とも思ってもしまったのです。

それは BOM あり BOM なし 2 種類のファイルを使って検証すれば、すぐに分かる話ではないでしょうか?
BOM の有無を調整する方法は、先に紹介した URL に書いてあります。

仮に「BOM 無しを前提としている処理系」に BOM 有ファイルを渡した場合、
 (a) BOM を文字として読み取り、先頭に U+FEFF すなわち「幅ゼロの無改行空白文字」として読み込む。
 (b) BOM を自動的に切り取って処理してくれる。(BOM 有無を自動判定するタイプ)
のいずれかになると思います。

a の場合は、最初の行の最初の列に、不可視文字が一文字混入するという事です。


> 先日教えてもいただいた「WriteLine → Write」での、
> そのままでは改行がされないがため、安直にも「sr.WriteLine()」が為にも関わらず。

その処理系では期待されている改行は LF ですか? CRLF ですか? あるいは CR ですか?

現状は、CSV ということと、それが UTF-8(BOMなし) という点しか分からないので、
仕様を出している担当者に、もっと突っ込んで確認した方が良いかも知れませんね。


(1)ファイルの先頭にヘッダー行が含まれるの否か。
 常にヘッダーがあるパターン、常に無いパターン、あっても無くても良いパターン。

(2)各レコードは可変長なのか固定長なのか。
 固定長 CSV の場合、文字数固定なのかバイト数固定なのかも重要です。

(3)すべての行で列数が同一なのかどうか。また、その列数は幾つと定義されているのか。
 処理系によっては、行によって列数が異なる CSV なんてものもあります。

(4)レコード区切りは LF 改行なのか CRLF 改行なのか CR 改行なのか。
 固定長 CSV の場合、稀に改行を一切含まないという特殊な CSV がありえます。

(5)レコード区切りの改行がある場合、それは「レコードの末尾」に付与されるのか
 それとも「レコードとレコードの間」に付与されるのか。
 もしもレコード間改行という仕様だった場合、ファイル終端には改行が含まれません。

(6)それぞれのデータを引用部(")で囲むのか否か。
 すべて引用符で囲む CSV もあれば、すべてのデータを囲まない CSV もあります。
 文字列は囲むが、数値は囲まない CSV なんてもあります。日付を # で囲む処理系もあり。

(7)引用符で囲む CSV の場合、データ中に「カンマ」や「改行」が許可されるか否か。
 これらの特殊文字をデータに含む CSV は、ファイルの作成はさほど難しく無いものの
 ファイルの読み込み処理が複雑化する傾向にあります。
 Excel で生成した CSV の場合、データ内改行は LF 固定、レコード区切は CRLF だったりしますね。

(8)引用符で囲む CSV の場合、データ中に「引用符」が許可されるか否か。
 半角「"」だけでなく、全角「“」や「”」も含めて禁止という CSV もあれば、
 データ内の引用符を許可する CSV もありますが。
 引用符が許可される場合、それはどのように出力されるのかも重要です。

(9)データを含まないセルの出力仕様が決まっているか。
 たとえば、携帯電話番号を含む住所録な CSV データがあって、たとえば
  "田中A","07092895448","東京都"
 と出力されるような処理系において、携帯電話番号が無い場合の出力パターンとしては
  "田中B","","東京都"
  "田中C",,"東京都"
  "田中D",null,"東京都"
  "田中E",undefined,"東京都"
 などのパターンが考えられます。
 処理系によっては、田中B のパターンは「空文字列」として扱う(携帯電話が無い)ものとし、、
 田中C のパターンを「null」として扱う(携帯番号を持っているかどうか不明)ことで、
 両者を区別して使い分けていることがありました。
 (田中D や田中E のパターンは、話として聞いたことがあるだけで、実際に見たことは無いです)
引用返信 編集キー/
■98920 / inTopicNo.12)  Re[7]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (52回)-(2022/01/19(Wed) 23:53:11)
2022/01/21(Fri) 01:10:43 編集(投稿者)
No98918 (魔界の仮面弁士 さん) に返信

ありがとうございます。

> 実際には何も出力されていない(空文字列)とか…ですかね。

きっとあきれてもしまうようなことなんですよ。
改行のために、こんなことしてしまったのですから。

  For j = 0 To 5
      sr.Write(123 & ",")
  Next
  sr.WriteLine()

解決済み
引用返信 編集キー/
■98939 / inTopicNo.13)  Re[8]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ 魔界の仮面弁士 (3283回)-(2022/01/21(Fri) 12:00:21)
No98920 (ゆい さん) に返信
> sr.Write(123 & ",")
演算子を使う意味が無いので、
 sr.Write("123,")
で良い気が。


> きっとあきれてもしまうようなことなんですよ。
> 改行のために、こんなことしてしまったのですから。
1 列のみの CSV なら、各行のカンマの数は 0 個です。
2 列構成の CSV なら、各行のカンマの数は 1 個です。
3 列構成の CSV なら、各行のカンマの数は 2 個です。

10 列の CSV なら、カンマの数は 9 個です。


> For j = 0 To 5
> sr.Write(123 & ",")
> Next
> sr.WriteLine()
この処理だと、7 列の CSV になりますね。

列1 = 123 (j = 0 の時のWrite)
列2 = 123 (j = 1 の時のWrite)
列3 = 123 (j = 2 の時のWrite)
列4 = 123 (j = 3 の時のWrite)
列5 = 123 (j = 4 の時のWrite)
列6 = 123 (j = 5 の時のWrite)
列7 = 空欄 (j = 5 の時もカンマが付与されているので)


列7 にも数字を入れておく必要があったのに、それが空だったので、
『ValueError: could not convert string to float:』
のエラーになってしまったんじゃないかな。
解決済み
引用返信 編集キー/
■98960 / inTopicNo.14)  Re[9]: UTF-8(BOM無し)のCSVファイルを読み書き
□投稿者/ ゆい (53回)-(2022/01/21(Fri) 23:37:29)
No98939 (魔界の仮面弁士 さん) に返信

ありがとうございます。

>>sr.Write(123 & ",")
> 演算子を使う意味が無いので、
>  sr.Write("123,")
> で良い気が。

123はSingleで扱った数値なので単純にそのまま使ってるのです。


>> For j = 0 To 5
>> sr.Write(123 & ",")
>> Next
>> sr.WriteLine()

> 列7 にも数字を入れておく必要があったのに、それが空だったので、
> 『ValueError: could not convert string to float:』
> のエラーになってしまったんじゃないかな。

123,123,123,123,123,123,
エクセルでは気付かなかったのですが、メモ帳ではこのようにもなってるのですよね。
当然といえば当然なのですが、私の単純なミスって訳です(^^;









解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -