C言語 CSVファイルの読み込み - stdio.h - [ fscanf ]

2008.09.20 Saturday | by LRESULT


CSVファイルの読み込み方法は、少し特殊な事してます。

そもそも、CSVファイルとは、データが『,』(カンマ)で区切られているファイルの事で、
エクセルなんかでも作成、読み込みが出来るメジャーでシンプルな構造のファイルです。


で、CSVファイルを読み込むのに適しているのは、
書式付きで読み込む事が出来て、カンマ区切りで読み込んでくれるfscanf()関数ですので
早速、試してみます。

前回と内容は同じですが、カンマで区切られた
「comma.csv」というCSVファイルを読み込みます。

test01,10,11,1.0,1.1
test02,20,21,2.0,2.1
test03,30,31,3.0,3.1

「文字列,整数,整数,小数,小数」という並びなので、

以下のように書くと、読み込めそうな気がします・・

  while( ( ret = fscanf( fp, "%s,%d,%d,%f,%f", s, &n1, &n2, &f1, &f2 ) ) != EOF ){
    printf( "%s %d %d %f %f¥n", s, n1, n2, f1, f2 );
  }

ですが、これではダメなのです!

何故か?
というと、%sの箇所で「,」(カンマ)までも文字列として読み込んでしまって
無茶苦茶な結果となってしまうのです・・・






サンプルコード
というわけで、改めてCSVファイルの読み取り方法です。
文字列があると、カンマまで含まれて残念な結果になったのですが、
要するにカンマを含まないような指定をすれば良いわけです。

fscanf()やscanf()関数には%d%sなどの、
変換文字(変換仕様)と言われる指定方法があります。
その中に、%[^...] という変換文字があり、カッコ内の文字以外を読み込むという意味です。

つまり、%[^abc] の場合は、「abc」以外の文字を読み込むという指定が出来ます。
これを、CSVファイル読み込みにも利用してみます。
#include <stdio.h>

int main(void)
{
  FILE *fp;
  char *fname = "comma.csv";
  char s[100];
  int ret, n1, n2;
  float f1, f2;

  fp = fopen( fname, "r" );
  if( fp == NULL ){
    printf( "%sファイルが開けません¥n", fname );
    return -1;
  }

  while( ( ret = fscanf( fp, "%[^,],%d,%d,%f,%f", s, &n1, &n2, &f1, &f2 ) ) != EOF ){
    printf( "%s %d %d %f %f", s, n1, n2, f1, f2 );
  }

  fclose( fp );
  return 0;
}



結果
test01,10,11,1.0,1.1
test02,20,21,2.0,2.1
test03,30,31,3.0,3.1
どうでしょうか?上記のように表示されるはずです。
これで、正しく読み込まれました。

%[^,] を使用することにより、カンマ以外の文字列を読み込むという指定が
出来るわけです。

カテゴリ:C言語 stdio.h | 21:29 | comments(11) | trackbacks(0) | -


コメント

csv形式へ変換したexcelファイルを、一行ずつ読み込みプログラム内の配列に保存。
一行読み込んだらまた次の行を読み込む、というプログラムを作りたいのですが、プログラム側から読み込む行や列を指定することはできるでしょうか?

| てばさき | 2009/10/29 5:19 PM |

コメント

>>てばさきさん

fgets関数を使ってみてください。

| akei | 2010/08/02 4:31 PM |

コメント

printf( "%s %d %d %f %f", s, n1, n2, f1, f2 );
に¥nがないのに出力結果に改行が入っているのはどうしてですか?

| レバ | 2010/09/04 8:06 PM |

コメント

test01,10,11,1.000000,1.100000
test02,20,21,2.000000,2.100000
test03,30,31,3.000000,3.100000
,30,31,3.000000,3.100000

結果が上のようになってしまいました。
何か入力ミスでしょうか。

| kawachi | 2011/02/09 1:51 PM |

コメント

結果が以下のようになります。
1行多く、最初の文字列がなく表示されます。

test01,10,11,1.0,1.1
test02,20,21,2.0,2.1
test03,30,31,3.0,3.1
30,31,3.0,3.1

borland cを使用。

| Kawachi | 2011/02/14 1:01 AM |

コメント

管理者の承認待ちコメントです。

| - | 2011/05/23 5:27 AM |

コメント

管理者の承認待ちコメントです。

| - | 2011/07/04 12:15 PM |

コメント

管理者の承認待ちコメントです。

| - | 2013/12/19 7:30 PM |

コメント

管理者の承認待ちコメントです。

| - | 2014/03/07 12:36 PM |

コメント

管理者の承認待ちコメントです。

| - | 2014/12/04 4:47 PM |

コメント

管理者の承認待ちコメントです。

| - | 2016/10/27 1:22 AM |

コメントする











この記事のトラックバックURL

http://simd.jugem.jp/trackback/49

トラックバック