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

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

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

Re[3]: CSVファイルを読み込む際に改行を消さないようにするには?


(過去ログ 124 を表示中)

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

■73874 / inTopicNo.1)  CSVファイルを読み込む際に改行を消さないようにするには?
  
□投稿者/ タカ (1回)-(2014/11/12(Wed) 00:46:52)

分類:[C#] 

2014/11/12(Wed) 00:54:48 編集(投稿者)

現在、以下の方法で
CSVを読み込むと、
連続改行が消されてしまいます。

TextFieldParser parser = new TextFieldParser("test.csv");
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
string[] row = parser.ReadFields();
}

1つの列に改行を含む文章があった場合

test.csvの一番目の列のデータが次のようなデータの場合
--------
一列目
--------
ああ


いいい
--------
下記のようになります。
--------
一列目
--------
ああ
いい
--------
この改行を消さないようにする方法は
どのようにすればよいですか?


引用返信 編集キー/
■73875 / inTopicNo.2)  Re[1]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ WebSurfer (379回)-(2014/11/12(Wed) 02:15:38)
No73874 (タカ さん) に返信

> この改行を消さないようにする方法は
> どのようにすればよいですか?

改行コードやデリミタがフィールド値の中にある場合、フィールド値をダブルクォー
ト (") で囲むと言った約束を設けて対応します。質問者さんが書かれたような CSV
データの形式では何ともなりません。

CSV データのフィールド値をダブルクォートで囲った上で、HasFieldsEnclosedInQuotes
プロパティを true に設定すればいいはずです。
引用返信 編集キー/
■73910 / inTopicNo.3)  Re[2]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ ainax (2回)-(2014/11/14(Fri) 08:46:14)
No73875 (WebSurfer さん) に返信
No73875 (WebSurfer さん) に返信

おそらく TextfieldParser では空行がうまく処理できないかと思います。
(ReadLine で1行読んで、ダブルクォートを自前で処理する方法ならいけると思いますが、
ReadField が使えないなら TextfieldParser を使うメリットが・・・)

もしも空行含め手軽に処理したい場合は、 CsvHelper というライブラリを使われると
いいかもしれません。

Nuget で install-package CsvHelper と打ち込めば自動で参照設定までしてくれます。

使い方は TextfieldParser とはだいぶ違いますが、後々の処理を考えると CsvHelper は
いろいろとカスタマイズした読み込み、書き込みができて楽だと思います。
(1行目を列名と指定したり、その列名を指定して必要な列だけ読み込んだり、
文字列としてではなく、数値や日付の型指定で読み込んだり書き込んだりできます。)

基本的な使い方は、

C:\myData.csv - - - - - - - - - - - -
1, saitou
2, suzuki
3, katou
4, yoshia
- - - - - - - - - - - - - - - - - - - - -

class myData{
public int id {get; set;}
public string name {get; set;}
}

class myDataMapper : CsvClassMap<myData>{
public myDataMapper(){
Map( m => id ); // Map( m => id ).index(0); でもOK。1行目が列名であれば、Map( m => id ).name("id") という形でも読み込めます。ただし1行目が列名だと設定しないとダメだったかも。
Map( m => name);
}
}

class main{
public static void main(){
using( var sr = new IO.StreamReader(@"C:\myData.csv")){
var reader = new CsvReader( sr );
var csv = reader.GetRecords<myData>().ToList();

foreach(myData data in csv){
console.WriteLine("id : {0}, name : {1}", data.id, data.name);
}
}
}
}
// ※IDEからコピーしてないので、エラーがあったら自前で直してください。

こんな感じに自前のクラスに Csv のデータを読み込んでいく感じです。

引用返信 編集キー/
■73917 / inTopicNo.4)  Re[3]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ WebSurfer (384回)-(2014/11/14(Fri) 14:09:15)
No73910 (ainax さん) に返信

実際に検証してみました。

TextFieldParser は、フィールドをダブルクォート (") で囲えば、空白のフィールド ("") は
認識しますが、改行コードのみのフィールド("<CR><LF>")は空白のフィールドと同じと認識す
るという結果でした。

JET を使うと、空白のフィールド ("") と改行コードのみのフィールド("<CR><LF>")は識別
できるようです。

(1) メモ帳で以下の内容の csv ファイルを作成。

"aaaa","bbbb","cccc"
"ddd","ee
ee","ffff"
"gggg","","iiii"
"jjjj","
",""

(2) 以下のコードで cvs ファイルを読んでその中身を書き出す。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Text.RegularExpressions;
using System.Data;

namespace ConsoleApplication3
{
    class Program
    {
        static void Main(string[] args)
        {
            // TextFieldParser を使う場合
            using (Microsoft.VisualBasic.FileIO.TextFieldParser tfp =
              new Microsoft.VisualBasic.FileIO.TextFieldParser(
                "test.csv",
                Encoding.GetEncoding("Shift_JIS")
              )
            )
            {
                tfp.TextFieldType =
                  Microsoft.VisualBasic.FileIO.FieldType.Delimited;
                tfp.Delimiters = new string[] { "," };
                tfp.HasFieldsEnclosedInQuotes = true;
                tfp.TrimWhiteSpace = true;

                while (!tfp.EndOfData)
                {
                    string[] fields = tfp.ReadFields();
                                        
                    for (int i = 0; i < fields.Length; i++)
                    {
                        fields[i] = fields[i].Replace("\r", "<cr>");
                        fields[i] = fields[i].Replace("\n", "<lf>");
                        
                        if (fields[i] == String.Empty)
                        {
                            fields[i] = "<empty>";                            
                        }

                        Console.Write(fields[i] + " ");
                    }
                    Console.WriteLine("");
                }
            }
            Console.WriteLine("------------------------------------");

            // Jet Provider を使う場合
            string csvDir = @"C:\Users...";  // csv ファイルのあるディレクトリ
            
            string conString =
              "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
              csvDir +
              ";Extended Properties=\"text;HDR=No;FMT=Delimited\"";

            System.Data.OleDb.OleDbConnection con =
              new System.Data.OleDb.OleDbConnection(conString);
            string commText = "SELECT * FROM [test.csv]";
            System.Data.OleDb.OleDbDataAdapter da =
              new System.Data.OleDb.OleDbDataAdapter(commText, con);

            DataTable dt = new DataTable();
            da.Fill(dt);

            foreach (DataRow row in dt.Rows)
            {
                foreach (DataColumn column in dt.Columns)
                {
                    // フィールドが "" の場合 row[column] は DBNull.Value になるので注意
                    string field = row[column] as String;
                    if (field != null)
                    {
                        field = field.Replace("\r", "<cr>");
                        field = field.Replace("\n", "<lf>");                        
                    }
                    else
                    {
                        field = "<empty>";
                    }
                    Console.Write(field + " ");
                }
                Console.WriteLine("");
            }
        }
    }
}


(3) 上記コードの実行結果。

aaaa bbbb cccc
ddd ee<cr><lf>ee ffff
gggg <empty> iiii
jjjj <empty> <empty>
------------------------------------
aaaa bbbb cccc
ddd ee<cr><lf>ee ffff
gggg <empty> iiii
jjjj <cr><lf> <empty>

引用返信 編集キー/
■73928 / inTopicNo.5)  Re[4]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ WebSurfer (386回)-(2014/11/15(Sat) 13:09:22)
すみません、前にアップしたコードで「TextFieldParser を使う場合」の方に誤り
がありました。

誤: tfp.TrimWhiteSpace = true;
   ↓
正: tfp.TrimWhiteSpace = false;

「誤」の方では改行コードもトリムされて "<CR><LF>" が "" になってしまいます。

訂正した後のコード実行結果は以下の通り、フィールド "<CR><LF>" の中の改行コー
ドは期待通り抽出されました。

aaaa bbbb cccc
ddd ee<cr><lf>ee ffff
gggg <empty> iiii
jjjj <cr><lf> <empty>
------------------------------------
aaaa bbbb cccc
ddd ee<cr><lf>ee ffff
gggg <empty> iiii
jjjj <cr><lf> <empty>

引用返信 編集キー/
■73970 / inTopicNo.6)  Re[2]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ 桜島 (1回)-(2014/11/18(Tue) 13:00:15)
No73875 (WebSurfer さん) に返信
> 改行コードやデリミタがフィールド値の中にある場合、フィールド値をダブルクォー
> ト (") で囲むと言った約束を設けて対応します。質問者さんが書かれたような CSV
> データの形式では何ともなりません。

はあ!?
データがフィールドの値を指していると仮定するなら
ダブルクオートは説明のために省略したのだろ。

"ああ


いいい"

こういうこと。

データがCSVファイルの内容であると仮定するなら

ああ


いいい

こうなる。
お前がやってることって検証になってないぞ。
あといつもお前が他人に言ってることだがゴミのようなコード貼るな。見る気がしない。
いいかげん頓珍漢治せよ。桜島さんが頭部切開してやろうか?おーん?
引用返信 編集キー/
■73971 / inTopicNo.7)  Re[3]: CSVファイルを読み込む際に改行を消さないようにするには?
□投稿者/ 優希(ゆき) (13回)-(2014/11/18(Tue) 13:50:57)
No73970 (桜島 さん) に返信
> ■No73875 (WebSurfer さん) に返信
>>改行コードやデリミタがフィールド値の中にある場合、フィールド値をダブルクォー
>>ト (") で囲むと言った約束を設けて対応します。質問者さんが書かれたような CSV
>>データの形式では何ともなりません。
>
> はあ!?
> データがフィールドの値を指していると仮定するなら
> ダブルクオートは説明のために省略したのだろ。
>
> "ああ
>
>
> いいい"
>
> こういうこと。
>
> データがCSVファイルの内容であると仮定するなら
>
> ああ
>
>
> いいい
>
> こうなる。
> お前がやってることって検証になってないぞ。
> あといつもお前が他人に言ってることだがゴミのようなコード貼るな。見る気がしない。
> いいかげん頓珍漢治せよ。桜島さんが頭部切開してやろうか?おーん?

教えてあげたいならあなたが、懇切丁寧に教えてあげればいいんじゃないかな?(笑)
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -