C言語関係掲示板

過去ログ

No.379.CSVファイルの読み込み

[戻る] [ホームページ]
No.2515

CSVファイルの読み込み
投稿者---初心者(2002/08/27 11:34:41)


CSVファイルを読み込み、データを格納したいのですが、やり方がいまいちよくわかりません。まず、CSVファイルの内容は
abcd,efgh,ijkl,mnop

となっています。これをコマンドパラメータとしてfgets関数で読み込んだ後、
struct AAA{
char a[4][10];
}data;
に格納したいのですが、
data->a[4][10]={s};
という表記はどこがまずいのでしょうか?

No.2516

Re:CSVファイルの読み込み
投稿者---TDa(2002/08/27 13:18:23)


>data->a[4][10]={s};
>という表記はどこがまずいのでしょうか?
このsと言うのがなんだかわかりません。
char s[BUFSIZE];
のようになっているのだとしたらこんな文はコンパイルを通りません。
文字列をコピーするときは一文字づつ処理するかstrcpyを使いましょう。

No.2518

Re:CSVファイルの読み込み
投稿者---初心者(2002/08/27 14:08:53)


すいません、sというのはfgetsで読み込んだ1行の文字列のつもりなのですが、','が3つなのでカラム数が4、カラムサイズが10という事で2次配列にして格納しようかと思ったのですが・・・。


No.2519

Re:CSVファイルの読み込み
投稿者---TDa(2002/08/27 15:20:04)


>すいません、sというのはfgetsで読み込んだ1行の文字列のつもりなのですが、','が3つなのでカラム数が4、カラムサイズが10という事で2次配列にして格納しようかと思ったのですが・・・。

まず','区切りの前にたとえば
char s[] = "hoge";
char t[10];
のとき"hoge"をtにコピーするにはどうするかわかっていますか?
t = sではだめですよ。

さて下のようなコードを書いてみました。ちょっとズルをしてsの最後にも','
がついています。この方がコードがすっきりしますので。仕様が厳格ならば
それに対応するのはご自分で考えてみてください。

#include <stdio.h>
#include <string.h>

int main(void)
{
        char s[] = "abcd,efgh,ijkl,mnop,";
        char data[4][10];
        int i, j, k;
        
        i = j = k = 0; 
        while (s[i] != '\0') {
                /* ','が区切り */
                if (s[i] == ',') {              
                        data[k++][j] = '\0';
                        ++i;
                        j = 0;
                }
                data[k][j++] = s[i++];
        }
        
        for (i = 0; i < 4; ++i) 
                printf("%s\n", data[i]);

        return 0;

}




No.2521

Re:CSVファイルの読み込み
投稿者---かずま(2002/08/27 15:50:40)


> さて下のようなコードを書いてみました。

そのプログラムは、data[4][0] に '\0' を書き込んでしまいます。
else を付けましょう。

No.2523

Re:CSVファイルの読み込み
投稿者---TDa(2002/08/27 20:31:52)


>そのプログラムは、data[4][0] に '\0' を書き込んでしまいます。
>else を付けましょう。

うっかりしていました。確かにelse節がいります。配列の配列があるために
インデックス変数がたくさんあって注意しないとだめですね。

一時バッファが増えて効率も悪くなりますがコードは読みやすいかと思って
最初に書いた方のコードも投稿します。こっちもelse節はなかったのですが
潜在的な危うさがあったのでインクリメントの場所なども気をつけたつもり。

#include <stdio.h>
#include <string.h>

int main(void)
{
        char s[] = "abcd,efgh,ijkl,mnop,";
        char data[4][10];
        char temp[100];
        int i, j, k;
         
        for (i = j = k = 0; s[i] != '\0'; ++i) {
                /* ','が区切り */
                if (s[i] == ',') {              
                        temp[j] = '\0';
                        strcpy(data[k], temp);
                        ++i; 
                        ++k; 
                        j = 0;
                } else {
                        temp[j] = s[i];
                        ++j;
                }
        }
        
        for (i = 0; i < 4; ++i) 
                printf("%s\n", data[i]);

        return 0;
}


No.2525

Re:CSVファイルの読み込み
投稿者---かずま(2002/08/27 22:43:57)


> 一時バッファが増えて効率も悪くなりますがコードは読みやすいかと思って
> 最初に書いた方のコードも投稿します。

s についての単一ループにするよりも、
data についての二重ループにしたほうが、分かりやすくなると思うんですが。
    for (i = j = 0; j < 4; j++, i++) {
        for (k = 0; s[i] != ',' ; k++)
            data[j][k] = s[i++];
        data[j][k] = '\0';
    }
sscanf を使って書くとこうなります。
    sscanf(s, "%9[^,],%9[^,],%9[^,],%9[^,]", data[0], data[1], data[2], data[3]);