掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.28005

カンマ区切りでの読み込み
投稿者---sys(2006/08/30 23:24:30)


初めまして
ファイルの内容をカンマ区切りで取得したいのですが、
どうしたらできるでしょうか。

例えばファイルに aaa,bbb,ccc とあったら
aaaを変数xに、bbbを変数yに、cccを変数zに、というふうにしたいんです。
どうか教えてください、お願いします。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:カンマ区切りでの読み込み 28006 YuO 2006/08/30 23:41:11


No.28006

Re:カンマ区切りでの読み込み
投稿者---YuO(2006/08/30 23:41:11)


>ファイルの内容をカンマ区切りで取得したいのですが、
>どうしたらできるでしょうか。

単純なカンマ区切りであれば,strtokで可能です。
ただし,空の列は無視されるので,条件を満たさないのであれば自分で作る必要があります。
過去ログをCSVで検索すると,それなりに見つかりますので,参考になるかと。



この投稿にコメントする

削除パスワード

No.28007

Re:カンマ区切りでの読み込み
投稿者---sys(2006/08/31 14:01:27)


>単純なカンマ区切りであれば,strtokで可能です。
ありがとうございます。
まだ試してはいませんが僕でもできそうです。
次に質問する時は過去ログもちゃんと見てきます。
ありがとうございました。


この投稿にコメントする

削除パスワード

No.28014

Re:カンマ区切りでの読み込み
投稿者---sys(2006/08/31 23:58:06)


FILE *fp;
int i,n=0
char s[256],*t1[100],*t2[100],*t3[100],*ret

fp=fopen("test.txt","r");
while(fgets(s,256,fp)!=NULL){
    t1[i]=strtok(s,",");
    t2[i]=strtok(NULL,",");
    t3[i]=strtok(NULL,",");
    n++;
}
fclose(fp);

for(i=0;i<n;i++){
    printf("%s\n",t1[i]);
    printf("%s\n",t2[i]);
    printf("%s\n\n",t3[i]);
}

return(0);

(エラー処理などは省略)


このようなコードを書いて見たんですがどうもうまくいきません。
コンパイルは通りますが、実行すると
「問題が発生したため、test.exe を終了します。」とエラーメッセージが表示されます。

要は、ファイルに
a,bb,ccc
ddd,ee,ffff
…(複数行続く)
とあるものを
1行目はaをt1[0]に、bbをt2[0]に、cccをt3[0]に(以下の行も同様に)格納したいんです。
この考え方が間違ってるんだと思っていますがこれ以上のことが思いつきませんでした。
どうか教えてください。お願いします。


この投稿にコメントする

削除パスワード

No.28015

Re:カンマ区切りでの読み込み
投稿者---shu(2006/09/01 00:09:44)


iを増やしていかないと、多分sysさんの思うように、
t1[i]、t2[i]、t3[i]に代入できない。

nは、fgets()しているループを抜けたところで、iの値を代入すればいい。



この投稿にコメントする

削除パスワード

No.28016

上の書きこみNo.28015は、間違いです。
投稿者---shu(2006/09/01 00:12:17)


>iを増やしていかないと、多分sysさんの思うように、
>t1[i]、t2[i]、t3[i]に代入できない。
>
>nは、fgets()しているループを抜けたところで、iの値を代入すればいい。

間違いですので参考にしないで下さい。


この投稿にコメントする

削除パスワード

No.28017

Re:カンマ区切りでの読み込み
投稿者---YuO(2006/09/01 01:11:02)


>このようなコードを書いて見たんですがどうもうまくいきません。
>コンパイルは通りますが、実行すると
>「問題が発生したため、test.exe を終了します。」とエラーメッセージが表示されます。

デバッグしましょう,しか言いようがないです。


>1行目はaをt1[0]に、bbをt2[0]に、cccをt3[0]に(以下の行も同様に)格納したいんです。
>この考え方が間違ってるんだと思っていますがこれ以上のことが思いつきませんでした。

今回の場合,読み取りバッファにsという単一のものを利用しています。
strtokは文字列を複製して返すわけではなく,元の文字列を書き換えて元の文字列中のポインタを返すだけなので,
2行目を読み込んだ時点で1行目のデータはなくなります。
# ポインタ自体は有効なので,2行目の途中を指していたりするでしょうが。

今回のように読み込んで溜める場合は,mallocを使って文字列にメモリを割り付ける必要があります。
# そのまま表示すれば問題ない。



この投稿にコメントする

削除パスワード

No.28018

Re:カンマ区切りでの読み込み
投稿者---sys(2006/09/01 21:17:39)


>strtokは文字列を複製して返すわけではなく,元の文字列を書き換えて元の文字列中のポインタを返すだけなので,
>2行目を読み込んだ時点で1行目のデータはなくなります。
そういう事だったんですか。ポインタを取得しても意味がなかったわけですね。
ということでポインタを取得してすぐに、そのポインタの示す文字列を取得する方法でやりました。

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

struct mydata
{
    char pr1[256];
    int pr2;
    double pr3;
};

int main(void)
{
    FILE *fp;
    int i,n=0;
    char s[256],tmp[256],*pt,*ret;
    struct mydata dt[100];
    
    fp=fopen("test.txt","r");
    while(fgets(s,256,fp)!=NULL){
        /* 文字列 */
        pt=strtok(s,",");
        strcpy(dt[n].pr1,pt);
        /* int型 */
        pt=strtok(NULL,",");
        strcpy(tmp,pt);
        dt[n].pr2=atoi(tmp);
        /* double型 */
        pt=strtok(NULL,",");
        strcpy(tmp,pt);
        dt[n].pr3=atof(tmp);
        n++;
    }
    fclose(fp);
    
    for(i=0;i<n;i++){
        printf("%s\n",dt[i].pr1);
        printf("%d\n",dt[i].pr2);
        printf("%f\n\n",dt[i].pr3);
    }
    
    return(0);
}


もっと効率の良い方法はこれから勉強していきます。
どうもありがとうございました。


この投稿にコメントする

削除パスワード

No.28019

Re:カンマ区切りでの読み込み
投稿者---nano(2006/09/01 22:17:08)


今回のプログラムではそれほど気にする必要がないのかもしれませんが、
今後、別の局面で、より堅牢で保守性の高いプログラムを開発するためには
以下の点に留意なさった方がいいのではないかと、老婆心ながら思いました。

1)ファイルのオープンに失敗したとき(fopenからNULLが返ったとき)の
処理を追加する方がよい。
2)256という、いわゆる「マジックナンバー」があちこちに
出てこない方がよい。enumか#defineを使うとよい。


この投稿にコメントする

削除パスワード

No.28020

Re:カンマ区切りでの読み込み
投稿者---sys(2006/09/02 00:02:44)


ご忠告ありがとうございます。
僕も普段ならば、見やすく保守性のあるコーティングをしてるのですが、(もちろんエラー回避や例外処理も)今回ばかりはパソコン甲子園というものに出場するのでそういう処理に時間をかけられなさそうなんです。

普段のプログラムは美しいコードを目指していきますので、これからも質問することがあったらよろしくお願いします。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧