C#ジェネリックメソッドでCSVの読み込み方法を教えてください

このQ&Aのポイント
  • C#ジェネリックメソッドを使用してCSVファイルを読み込む方法を知りたいです。Double.Parseメソッドをどのように変更すればいいかわかりません。
  • CSVファイルをdouble配列に格納するC#のメソッドをジェネリックにしたいです。Double.Parseメソッドの部分をどう変更すればいいかわかりません。
  • C#のジェネリックメソッドを使用してCSVファイルを読み込む方法を知りたいです。具体的には、Double.Parseメソッドの部分をどのように変更すればいいか教えてください。
回答を見る
  • ベストアンサー

C# ジェネリックメソッドでCSVの読み込み

以下のメソッドをジェネリックメソッドにしたいのですが、 Double.Parseメソッドの部分をどう変更したらいいのかわかりません。 どなたか方法を教えてください! //CSVデータをdouble配列に格納する public static void readCSV(double[] a, string filePath) { int i = 0; char delimiter = ','; //区切り文字はカンマ string line = ""; using (StreamReader r = new StreamReader(filePath)) { while ((line = r.ReadLine()) != null) // 1行ずつ読み出し。 { //分割した結果を文字列の配列で受け取る string[] splittedResult = line.Split(delimiter); a[i] = (Double.Parse(splittedResult[0])); i++; } } } //ジェネリックバージョン public static void readCSV<Type>(Type[] a, string filePath) { int i = 0; char delimiter = ','; //区切り文字はカンマ string line = ""; using (StreamReader r = new StreamReader(filePath)) { while ((line = r.ReadLine()) != null) // 1行ずつ読み出し。 { //分割した結果を文字列の配列で受け取る string[] splittedResult = line.Split(delimiter); //Double.ParseをTypeを用いてどう記述していいかわからない a[i] = (Double.Parse(splittedResult[0])); i++; } } }

noname#228769
noname#228769

質問者が選んだベストアンサー

  • ベストアンサー
  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

ReflectionでParseメソッドを呼ぶ。 private T Parse<T>(string s) { System.Reflection.MethodInfo m = typeof(T).GetMethod( "Parse", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, new Type[]{typeof(string)}, null); return (T)m.Invoke(null, new object[] { s }); }

noname#228769
質問者

お礼

ありがとうございます!出来ました!

関連するQ&A

  • c#で(",")区切りのcsvファイルから読み込みを行うには?

    駆け出しの初心者です。 以前c言語を少々勉強していてcsvファイルの読み込み、書き出しを練習していたのですが、最近c#を使うようになり、その便利さに圧倒されております。 今回c#で読み込みたいcsvファイルは以下のようになっております "abc","123","あいうえお" ただのカンマ区切りであれば読み込みは簡単ですが、 上記のようにダブルクオーテーションでそれぞれの文字列が囲まれている場合に文字列だけを読み込み、配列に代入していくのに何かスムーズな方法はありませんでしょうか? ちなみに現在単純にカンマ区切りのcsvファイルを読み込むコードを 書いた所ですので、載せておきます これをいじってスムーズにいければうれしいのですが、いかがでしょうか? private void LoadData() { string path = "Data.csv"; string delimStr = ",";//区切り文字 char[] delimiter = delimStr.ToCharArray(); string[] strData;//分解後の文字用変数 string strLine;//1行分のデータ Boolean fileExists = System.IO.File.Exists(path); if (fileExists) { System.IO.StreamReader sr = new System.IO.StreamReader( path, System.Text.Encoding.Default); while (sr.Peek() >= 0) { strLine = sr.ReadLine(); strData = strLine.Split(delimiter); DataSet.DataTable.AddDataTableRow( DateTime.Parse(strData[0]), strData[1],    strData[2], int.Parse(strData[3]), strData[4]); } sr.Close(); } } いつも丁寧な回答で協力してくれる皆様には心から感謝しております。 どうぞよろしくお願いします。

  • C#で配列の値をチェックするメソッドを書きたい

    C#の配列についてお教え頂けませんでしょうか? CSVファイルから1行読取り、配列に格納しています。 string[] rowdata; string x; int y; double z; TextFieldParser Parser = new TextFieldParser(FILEPATH, Encoding.GetEncoding("shift_jis")); while (!Parser.EndOfData) { //1行読取り rowdata = csvParser.ReadFields(); //読み取った値を変数に x = rowdata[0]; //string y = rowdata[1]; //int z = rowdata[2]; //double } rowdata[0~3]を変数に格納する前に、データのチェックをおこないたいです。 例えば、rowdata[1]はint型変数に格納されます。しかしrowdata[1]に格納された値が「A1」とあった場合、int型変数yには格納できずエラーが起こります。 よって、rowdata[1]に数値以外の文字列があったら「0」に置き換えるなどの処理をいれたいです。 なので、配列を受け取ってデータチェックをするメソッドを作りたいと思いますが、どのように作っていいかがわかりません。 1つのメソッドでint、double、stringかどうかの、チェックを行いたいですが、そのようなことは可能なのでしょうか? 下記のように3つメソッドを作って、データをメソッドに渡しチェックを行なうのがいいのでしょうか? string CheckData(string[] arr){}; int CheckData(int[] arr){}; double CheckData(double[] arr){}; やりたい事は、 メソッド(配列を受取る) rowdata[0]が渡された場合、中身はstringかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[1]が渡された場合、中身はintかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 rowdata[2]が渡された場合、中身はdoubleかのチェック。問題なければ格納されている値を返す。問題があれば、何らかの処理。 以上のような事です。宜しくお願い致します。

  • C#のStreamReaderでのforeach

    StreamReader sr = new StringReader(filePath); foreach (Strins s in sr.ReadLine()) { } 上記プログラムでは 型'char'を'string'に変換できません。 と出てきて無理でした。 http://stackoverflow.com/questions/286533/filestream-streamreader-problem-in-c-sharp 此方を参考に、下記プログラムを書きました。 private static IEnumerable<string> ReadLine() { string str; while ((str = sr.ReadLine()) != null) { yield return str; } } private static void loop() { foreach (string str in ReadLine()) { } } 1. 下記のものは動くのですが、なぜ最初に書いたものではダメなのでしょうか? 2. もっと綺麗(スリム)に書くことはできないでしょうか? 3. string str; while ((str = sr.ReadLine()) != null) ↓ while((string str = sr.ReadLine()) != null) とするとエラーが出るのはなぜでしょうか? 宜しくお願いします。

  • csvの読み込みがうまく行かない

    こんにちは。質問させていただきます。 (Visual Basic 2010 エクスプレス) 下記のように書いたのですが、ファイルの内容どおりに読み込んでくれません。 ファイルの中身は さささ,0,ししししししし すすす,0,せせせせせせ そそそ,0,たたたたた となっているのですが、最初の一行を読み込み、しかも最初の一行を繰り返し2段目3段目の テキストボックスに表示させてしまいます。 具体的には さささ ししししししし さささ ししししししし さささ ししししししし です。 本来は さささ ししししししし すすす せせせせせせ そそそ たたたたた と表示させたいのです。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click Using reader As New System.IO.StreamReader("C:\csvtest\test.csv", System.Text.Encoding.GetEncoding("Shift-JIS")) Dim Items() As String 'CSVの各項目を表す配列 Dim Line As String = reader.ReadLine 'CSVの一行 Do Until IsNothing(Line) Items = Line.Split(",") '一行を, (カンマ)で区切って項目ごとに分解 With reader TextBox1.Text = Items(0) CheckBox1.CheckState = Items(1) TextBox2.Text = Items(2) Line = reader.ReadLine '次の行を読み込む。 TextBox3.Text = Items(0) CheckBox1.CheckState = Items(1) TextBox4.Text = Items(2) Line = reader.ReadLine '次の行を読み込む。 TextBox5.Text = Items(0) CheckBox1.CheckState = Items(1) TextBox6.Text = Items(2) Line = reader.ReadLine '次の行を読み込む。 .Close() End With Loop End Using End Sub 問題点がわかる方、よろしくおねがいします!

  • c#でcsvから指定の1行だけを読み込む方法

    以前c言語で同じような質問をして、とても有益な回答を頂きましたが、 今回c#でのコードの書き方をご教示いただければと思い、再度質問致します。 例えば以下のようなcsvファイルがあったとします。 ab1,ef2,ab3,af4,ab5 bb1,bf2,bb3,bf4 cb1,cf2,cb3,cf4,cb5 zb1,zf2,zb3,zf4,zb5 プログラムに"cb3"という文字列を探させて、その文字列を含む一行 "cb1,cf2,cb3,cf4,cb5"のみを読み込む方法を探しております。 現時点では以下のコードにてcsvファイルを丸々読み込んでおります。 private void LoadData()//csvファイルを読み込む { string path = "abc.csv"; string delimStr = ",";//区切り文字 char[] delimiter = delimStr.ToCharArray();//区切り文字をまとめる string[] strData;//分解後の変数 string strLine; //1行分のデータ Boolean fileExists = System.IO.File.Exists(path); if (fileExists) { System.IO.StreamReader sr = new System.IO.StreamReader( path, System.Text.Encoding.Default ); while (sr.Peek() >= 0) { strLine = sr.ReadLine(); strData = CsvToArrayList1(strLine)[0]; abc.abctable.AddabctableRow ( strData[0], int.Parse(strData[1]) ); } sr.Close(); } c言語の時はstrstrで特定の文字を含む1行のみを取得できたのですが、 c#ではもっと良い方法があるのではと考えております、 お時間がありましたら是非教えてください。 皆様の丁寧な回答にいつも感謝しております。

  • CSVの読み込みについて

    いつもお世話になります。 TextBox1に品物のコードを入れて、Label1に価格を表示するという簡単そうなものです。 品物のコードはCSVファイルのItem(1)から取得します。ところが存在しないコードを入力すると、 追加情報 : インデックスが配列の境界外です というエラーが出ます。下記ソースに何を追加すればよろしいのでしょうか?ご教授下さい。よろしくお願い致します。 Dim Reader As New IO.StreamReader("C:\XXX.csv", System.Text.Encoding.GetEncoding("Shift-JIS")) Dim Items() As String Dim Line As String = Reader.ReadLine       Dim Code As String 'コード Dim kakaku As String '価格 Do Until IsNothing(Line) Items = Line.Split(",") Code = Items(1) If HinCode = TextBox1.Text Then kakaku = Items(2) Label1.Text = kakaku Exit Sub End If Line = Reader.ReadLine Loop Reader.Close()

  • 【C#】二次元配列へのcsvファイルの格納について

    いつもお世話になってます。 C#に関して質問です。 VisualC#2008を使用しています。 二次元配列の中にcsvファイルの内容を格納したいと思っています。 一次元配列だと、split(',')のようにコンマで区切って格納することができたのですが、 二次元配列になるとうまくいきません。 作成中のプログラム(一部)は下記のようになっています。 二次元配列になっても、csvファイルをうまく格納できる方法を誰かおしえていただけないでしょうか? よろしくお願いします。 private void 問題ファイルを読み込むXToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); if (ofd.ShowDialog() == DialogResult.OK) { System.IO.Stream stream; stream = ofd.OpenFile(); //StreamReaderオブジェクトの作成 StreamReader sr = new StreamReader(stream, Encoding.GetEncoding(932)); string dat; //文字を入れる while ((dat = sr.ReadLine()) != null) { sbuf = dat.Split(','); //エラー箇所 //DataGridViewに新しい行を追加 int r = dataGridView1.Rows.Add(); dataGridView1[0, r].Value = sbuf[mondai_count,0]; dataGridView1[1, r].Value = sbuf[mondai_count,1]; dataGridView1[2, r].Value = int.Parse(sbuf[mondai_count,2]); //Parseで文字列を数値に変換 } //visible=False でDataGridView非表示 mondai_bun[0] = sbuf[mondai_count,0]; mondai_title[0] = sbuf[mondai_count,1]; mondai_bun2.Text = mondai_bun[0]; this.mondai_list.Items.Add(mondai_title[0]); //ファイルを閉じる sr.Close(); stream.Close(); } }

  • C++でのtxtファイル読み込みについて

    こんにちは。 C++でのtxtファイル読み込みについて質問させていただきます。 下記のようなコードを使ってtxtファイルを読み込もうとしています。 private: System::Void toolStripButton2_Click(System::Object^ sender, System::EventArgs^ e) { array<int>^ x=gcnew array<int>(103*300); array<int>^ y=gcnew array<int>(103*300); int num=int::Parse(numericUpDown4->Text); String^ fileName="outputx"+ num.ToString() +".txt"; String^ string1; StreamReader^ sreader1; StreamReader^ din = File::OpenText(fileName); array<String^>^ sub_string; //指定したファイル名でStreamReaderを設定する try{ sreader1=gcnew StreamReader(fileName); }catch(Exception^ ex){ MessageBox::Show("!"); return; } //x[i]の読み込み String^ str; int count = 0; while ((str = din->ReadLine()) != nullptr) { string1=sreader1->ReadLine(); //StreamReaderに1行読み込む sub_string=string1->Split(' '); //コンマで分割する x[count]=Convert::ToInt32(sub_string[1]); y[count]=Convert::ToInt32(sub_string[2]); count++; } Bitmap^ bmap_dst=gcnew Bitmap(104,301); for(int j=0;j<301;j++) for(int i=0;i<104;i++){ bmap_dst->SetPixel(i,j,Color::FromArgb(255,255,255));} for(int k=0;k<count;k++){ bmap_dst->SetPixel(x[k],y[k],Color::FromArgb(0,0,0));} pictureBox1->Image = bmap_dst; pictureBox2->Image = bmap_dst; //y座標 fileName="outputy"+ num.ToString() +".txt"; String^ string2; StreamReader^ sreader2; din = File::OpenText(fileName); array<String^>^ sub_string2; //指定したファイル名でStreamReaderを設定する try{ sreader2=gcnew StreamReader(fileName); }catch(Exception^ ex){ MessageBox::Show("!"); return; } //x[i]の読み込み String^ str2; count = 0; while ((str2 = din->ReadLine()) != nullptr) { string2=sreader2->ReadLine(); //StreamReaderに1行読み込む sub_string2=string2->Split(' '); //コンマで分割する x[count]=Convert::ToInt32(sub_string2[1]); y[count]=Convert::ToInt32(sub_string2[2]); count++; } Bitmap^ bmap_dst2=gcnew Bitmap(104,301); for(int j=0;j<301;j++) for(int i=0;i<104;i++){ bmap_dst2->SetPixel(i,j,Color::FromArgb(255,255,255));} for(int k=0;k<count;k++){ bmap_dst2->SetPixel(x[k],y[k],Color::FromArgb(0,0,0));} pictureBox3->Image = bmap_dst2; pictureBox4->Image = bmap_dst2; } また、読み込むtxtファイルは下記のようなものです。(長いので途中部分のみ)      1    287      1    288      2    107      2    108      2    109      2    110 これをビルドすると”入力文字列の形式が正しくありません”と出てしまいます。 また、下記のようなtxtファイルだと問題なく読み込むことができます。 9 164 9 165 9 166 10 151 10 152 10 153 10 154 プログラミングのどこがいけないのでしょうか? 説明不足かと思いますが、ご回答よろしくおねがいします。

  • CSVファイルの読み込み

    以下のようなCSVファイルを読み込みたいと思っています。 0.575092,0.030525 0.565324,0.018315 0.555556,0.013431 0.553114,0.013431 0.54823,0.015873 0.538462,0.013431 0.531136,0.006105 0.52381,-0.003663 0.516484,-0.010989 0.501832,-0.015873 0.489622,-0.018315 0.477412,-0.020757 0.46276,-0.020757 ・ ・ ・ 50000*2のデータで、以下のようなプログラムを使用しました。 #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 50000 #define M 2 /* データの区切り文字 */ #define SEP_DATA ',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン */ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し */ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換 */ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す */ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す */ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ */ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保 */ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化 */ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み */ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力 */ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } しかし、コンパイルは通るのですが実行時にエラーが出てしまいます。 データの大きさに問題があると思うのですが、原因がわかりません。おかしな所のご指摘を頂きたいです。よろしくお願いします。

  • C++/CLIでのDataGridViewの使い方

    以前に質問させていただいたのですが、要点を得ていなかったため再度質問させていただいきます。 VC++2005のC++/CLIでプログラムを作成しています。 CSVファイルから内容を読み込み、DataGridVeiwに表示させたいと考えています。 CSVファイルを配列に読み込んで、表示するところまでは出来ています。 以下CSVファイルを読み込んで、コンソール出力するプログラムの一部 int i; StreamReader^ sr=gcnew StreamReader("hoge.csv"); String^ text=sr->ReadToEnd(); array<String^>^ line=text->Split(gcnew array<String^> {"\r\n", "\r", "\n"},StringSplitOptions::RemoveEmptyEntries); array<array<String^>^>^ table= gcnew array<array<String^>^>(line->Length); for (i=0; i<line->Length; i++) { table[i]=line[i]->Split(','); } for each (array<String^>^ output in table){ for(i=0; i<output->Length; i++){ Console::Write(output[i]); //行出力 } } 初歩的なことだとは思うのですが・・・ コンソール出力部分をDataGridViewで出力表示させるには どのように書けばいいでしょうか。 よろしくお願いします。

専門家に質問してみよう