No.2035![]() |
ファイル 投稿者---中村(2004/06/15 16:33:43) |
||
すいません。 掲示板http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200406/04060035.txtに投稿した内容なのですが、 初心者ゆえ、全く進展がないのが現状です。 しかし、このお話には興味があり、向上心はあります。ぜひともこの方法を習得したいと思います。 参考図書、インターネットを調べましたが、それにそった内容のものに縁がなく悩んでいます。 どうか、皆さんのお力を貸していただけないでしょうか。 教えてください。お願いします。 入力用のファイルをオープンする。 1行読み込んで何列あるか数える。 列数分、ファイルポインタ型の配列を確保する。 列数分繰り返し・ここから 出力用ファイル名を生成する。 出力用ファイルをオープンする。 列数分繰り返し・ここまで 行数分繰り返し・ここから 入力用ファイルから1行読み込む。 列数分繰り返し・ここから 空白文字をデリミタにして、1トークン切り出す。 切り出したトークンを、然るべき出力用ファイルに出力する。 列数分繰り返し・ここまで 行数分繰り返し・ここまで 入力用ファイルをクローズする。 列数分繰り返し・ここから 出力用ファイルをクローズする。 列数分繰り返し・ここまで |
No.2038![]() |
Re:ファイル 投稿者---えとな(2004/06/15 17:19:09) |
||
マルチポストはやめましょう。 向こうで教えてもらった内容をコピペして張り付けるなんて 教えてくれている方に失礼だとは思わないんですか? 向こうで教えてもらったことを一つずつやってみれば 少しはわかってくると思いますよ。 それとも、まさか解となるソースを載せてほしいわけじゃ ないですよね? |
No.2039![]() |
ファイル 投稿者---中村(2004/06/15 17:26:20) |
||
マルチはわかっていて投稿しました。 回答を前の掲示板に反映します。 |
No.2041![]() |
Re:ファイル 投稿者---かずま(2004/06/15 19:23:40) |
||
> しかし、このお話には興味があり、向上心はあります。ぜひともこの方法を > 習得したいと思います。 その方法でなくても申し訳ありませんが、別の方法を提示します。 ---------------------------------------------------------------------- 入力用のファイルをオープンする(標準入力を使ってもよい)。 1行読み込んで、文字列を切り出し、charポインタの配列に複写する。 使用した配列の要素の個数が、列の個数である。 ファイルの最後まで 文字列を charポインタの配列に読み込む。 列数分繰り返し・ここから 出力用ファイル名を列番号から生成する。 出力用ファイルをオープンする。 その列の文字列をすべて出力する。 出力用ファイルをクローズする。 列数分繰り返し・ここまで ---------------------------------------------------------------------- #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 10000 int main(void) { char *str[N], buf[1024], *p; int n = 0, i, j, col; FILE *fp; if (fgets(buf, sizeof buf, stdin) == NULL) puts("no data"), exit(1); for (p = buf; p = strtok(p, " \t\n"); p = NULL) str[n++] = strdup(p); col = n; while (scanf("%s", buf) == 1) { if (n == N) puts("too many data"), exit(1); str[n++] = strdup(buf); } for (i = 0; i < col; i++) { sprintf(buf, "file%02d.txt", i+1); fp = fopen(buf, "w"); if (fp == NULL) puts("can't create output file"), exit(1); for (j = i; j < n-col; j += col) fprintf(fp, "%s ", str[j]); fprintf(fp, "%s\n", str[j]); fclose(fp); } return 0; } 質問の方法と共通する部分がどこだか分かりますか? |
No.2214![]() |
ファイル操作 投稿者---中村(2004/07/02 20:28:53) |
||
前回は本当にお世話になりました。有難うございました。 あれから、自分でソースを完成させてここに提示したかったのですが、以下のままでつまづき、進むことが出来ません。考えてはいるのですが、かずまさんに教えていただいた 列数分繰り返し・ここから 出力用ファイル名を列番号から生成する。 出力用ファイルをオープンする。 その列の文字列をすべて出力する。 出力用ファイルをクローズする。 列数分繰り返し・ここまで の部分で出力することが出来ません。 もしよろしければ、ご教授していただきたいです。 お手数お掛けいたしますが、宜しくお願いいたします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1000 int main(void) { char *str[N], buf[1024], *p,*q; int n = 0, i, j, col; FILE *fp; /* ファイルのオープン */ /* ここで、ファイルポインタを取得する */ if ((fp = fopen("test.txt", "r")) == NULL) { printf("file open error!!\n"); exit(1); /* エラーの場合は,異常終了する */ } // //if (fgets(buf, sizeof buf, fp) == NULL) puts("no data"), exit(1); while (fgets(buf, sizeof buf, fp) != NULL) { if (fp == NULL) return 1; /* ここではfgets()により1行単位で読み出し */ printf("%s", buf); } for (p = buf; (q = strtok(p," \t\n")) != NULL; p = NULL) { str[n++] = strdup(q); //n++; col = n; } printf("%d\n",col); printf("%s\n",*str); while (scanf("%s", buf) == 1) { if (n == N) puts("too many data"), exit(1); str[n++] = strdup(buf); } printf("%s\n", *str); for (i = 0; i < col; i++) { sprintf(buf, "file%02d.txt", i+1); fp = fopen(buf, "w"); if (fp == NULL) puts("can't create output file"), exit(1); for (j = i; j < n-col; j += col) fprintf(fp, "%s ", str[j]); printf( "%s\n", str[j]); printf( "%s ", str[j]); fprintf(fp, "%s\n", str[j]); fclose(fp); } return 0; } |
No.2217![]() |
Re:ファイル操作 投稿者---RAPT(2004/07/03 09:43:14) |
||
col は初期化しないとまずいですね。 最初に読み込んだ行が無効な行だった場合、未初期化の変数を 参照することになってしまいます。 while (fgets(buf, sizeof buf, fp) != NULL) { if (fp == NULL) return 1;/* ここではfgets()により1行単位で読み出し */printf("%s", buf); } なんでここで (fp == NULL)のチェックが必要なのでしょうか? それから、whileループがここで完結していますが、当該処理は 最終行を抽出するのが目的でしょうか? コメントでは、読み出した1行ごとに処理を行なうような印象を 受けたのですが。 printf("%d\n",col); printf("%s\n",*str); これは、1つ目のデータを参照しようとしていますが、データ 個数が0のとき、アクセス違反となります。 while文直後の printf("%s\n", *str); これではwhile文直前のデータと同じモノを表示しようとして いますが、意図した処理でしょうか? fp = fopen(buf,"w"); この文が実行される前に、読み出しファイルのクローズが行わ れていません。このままでは読み出しファイルが壊れる可能性 があります。 for (j = i; j < n-col; j += col) fprintf(fp,"%s ", str[j]); このfor文は、(j < n-col) の評価結果は常に偽なので、直後の fprintf()文は実行されることはありません。 for文の前に、 fprintf(stderr, "i = %d, j = %d, n = %d, col = %d, j < n-col = %s\n", i, j, n, col, (j < n-col) ? "true" : "false"); とでも記載し、値の変化を確認するといいでしょう。 以上、脳内トレース結果でした。ご確認ください。 |
No.2218![]() |
Re:ファイル操作 投稿者---中村(2004/07/03 13:24:36) |
||
ご返信有難うございました。 PARTさんのご助言を下に現在考えております。 ><pre>col は初期化しました。 for文の前に、 fprintf(stderr, <font color="#0000ff">"i = %d, j = %d, n = %d, col = %d, j < n-col = %s\n"</font>, i, j, n, col, (j < n-col) ? <font color="#0000ff">"true" : "false"</font>); とでも記載し、値の変化を確認しようとしているのですが、出力できません。 なぜでしょうか。 |
No.2223![]() |
Re:ファイル操作 投稿者---RAPT(2004/07/04 14:31:05) |
||
そうか、ファイル読み込み後にデータが何かしら入力されたらfor文内が 実行されうるな。ってことでサンプルソース。 # 相変わらず何がやりたいのかわからなかったから、ファイル出力だけは # 元のソースと同じものを出力するようにした。 Windows2000sp4/VC++6.0sp6/Console-App #include <stdio.h> #include <stdlib.h> #include <string.h> #define N 1000 int main(void) { char *str[N] = {0}, buf[1024] = {0}, *p = NULL, *q = NULL; int n = 0, i = 0, j = 0, col = 0; FILE *fp = NULL; fp = fopen("test.txt", "r"); if (fp == NULL){ printf("file open error!!\n"); exit(1); } while (fgets(buf, sizeof buf, fp) != NULL){ printf("%s", buf); } fclose(fp); for (p = buf; (q = strtok(p," \t\n")) != NULL; p = NULL){ str[n++] = strdup(q); } col = n; while(n < N && scanf("%s", buf) == 1){ str[n++] = strdup(buf); } for (i = 0; i < col; i++) { sprintf(buf, "file%02d.txt", i+1); printf("FILE = %s\n", buf); // check fp = fopen(buf, "w"); if (fp == NULL){ puts("can't create output file"); goto END; } for (j = i; j < n - col; j += col){ printf("---for---:[%s]\n", str[j]); // check fprintf(fp, "%s ", str[j]); } printf("%s\n", str[j]); // check fprintf(fp, "%s\n", str[j]); fclose(fp); } END: for(i = 0; i < n; i++){ free(str[i]); } return 0; } |