
c言語 2つのファイルを行ごとに読み込むプログラミング
0.txt と 1.txt という2つのテキストフォルダがあり
0.txt の中身は
a a
b b
1.txt の中身は
c c
d d
というものとします。
これら2つのフォルダを読み込むとき
まず1つのフォルダの1行目(a a)を表示し
他方の1行目(c c) 2行目(d d)を表示させて
続いて1つのフォルダの2行目(b b)を表示し
他方の1行目(c c) 2行目(d d)を表示させたいのです。
つまり実行結果が
a a
c c
a a
d d
b b ←理想の実行結果です
c c
b b
d d
となるようにしたいのですが
#include <stdio.h>
#include <stdlib.h>
#define STR_MAX 256
int main(void)
{
FILE *fp, *fp2;
int i, j, k;
char buf[STR_MAX];
char buf2[STR_MAX];
fp = fopen("0.txt", "r");
fp2 = fopen("1.txt", "r");
if (fp == NULL && fp2 == NULL){
printf("\n");
}
while(fgets(buf, STR_MAX, fp) != NULL){
while(fgets(buf2, STR_MAX, fp2) != NULL){
printf("%s%s", buf,buf2);
}
printf("\n");
}
fclose(fp);
fclose(fp2);
return 0;
}
このプログラミングの実行結果は
a a
c c
a a
d d
となり、0.txtの2行目(b b)は表示されません。
おそらく while 文 を2重にすることで
不具合が起きているのだと思うのですが
色々と調べた結果、これ以外に
プログラミングが思いつきません。
私の理想の実行結果にするためには
どこを訂正させると良いのでしょうか?
恐れ入りますが ご回答 どうかよろしくお願いいたします。
No.3ベストアンサー
- 回答日時:
単純に 0.txt を一行読んで 1.txt を全て書き出すと考えます。
内側の while は一回働けば 1.txt をすべて読み込んでいますから、外側の while の二回目以降は EOF で働きません。
fgets関数をもう一度考え直してください。
内側の while でファイルの先頭から読み込ませる一番簡単な方法は、オープン/クローズを繰り返す方法です。
骨格だけですが。
fp = fopen("0.txt", "r");
while(fgets(buf, STR_MAX, fp) != NULL){
fp2 = fopen("1.txt", "r");
while(fgets(buf2, STR_MAX, fp2) != NULL){
printf("%s%s", buf,buf2);
}
fclose(fp2);
}
fclose(fp);
ありがとうございます。
実行結果は見事
私の理想通りになりました。
おっしゃる通りでfgets関数を考え直すべきだと思いました。
更に質問なのですが
たとえば 先ほどの例として出したテキストファイル
1.txt の中身を
a a
d d
としておなじ動作をおこなうとき
buf,buf2 が等しい時が(buf,buf2=a a)存在するので
if(buf == buf2){
printf("%s%s", buf,buf2);
}
とすれば、
実行結果が
a a
a a
と表示されると思ったのですが
何も表示されません。
buf = a a buf2 = a a
だとしても
if(buf == buf2)
は使えないのでしょうか?
No.4
- 回答日時:
すみません。
仕様を勘違いしていました。ファイルは基本的に、読み書きしたら、その位置のままです。
なので、最初から読み直す、といった、位置を変更したい場合はfseek関数やrewind関数を使います。
今回は先頭に戻すので、rewind関数が楽でしょう。
while(fgets(buf, STR_MAX, fp) != NULL){
rewind(fp2); /* 追加 */
while(fgets(buf2, STR_MAX, fp2) != NULL){
ただ、この方法は毎回ファイルを読み込むので(キャッシュで多少早くなる可能性はありますが)効率は悪いです。
ファイルサイズが小さく、メモリに余裕があるのなら、予め全部読み込んでおいて、対応する行だけ表示する、というのがいいのですが。
# 例によって、 Perlとかだと簡単だよなぁ、と思います。
No.1
- 回答日時:
whileに限らず、二重ループというのは、
外側1回目
内側1回目
内側2回目
内側3回目
...
内側最後
外側2回目
内側2-1回目
内側2-2回目
内側2-3回目
...
内側2-最後
外側3回目
...
というようにループするものです。
考え方ですが。
まず、「1回」で行う処理は何かを考えましょう。
今回のなら
{
0.txtを1行読み込んで、(読み込めたなら)表示する
1.txtを1行読み込んで、(読み込めたなら)表示する
}
というもののはずです。
次に、どんな風に繰り返すのかを考えます。
今回は「先頭行から最終行まで」ですよね。
順番に並んでいて、しかも1方向だけです。ということは、ループも1重で済むということです。
あとは、実装方法はいろいろあります。
・無限ループを作って、終了条件になったらbreakで抜ける。
・終了するかどうかのフラグ用の変数でループを制御する。
等々.
両ファイルの行数が違う場合とかエラーがあったときとかを考えると、ちょっと複雑になります。
両ファイルの行数が同じ場合で、エラー処理とか考えなければ
> while(fgets(buf2, STR_MAX, fp2) != NULL){
これを
> if(fgets(buf2, STR_MAX, fp2) != NULL){
こうすると、とりあえずは動作します。どうしてそうなるかは、よく考えてみてください。
あとは別件ですが。
> 0.txt と 1.txt という2つのテキストフォルダがあり
用語を誤解されています。
こういうものは「ファイル」といいます。
「フォルダ」というのは複数のファイルをまとめておける「ファイルの入れ物」です。
ファイルとフォルダとでは、プログラムの方法も変わってきます。今回は例があったので「ファイル」の誤用だとわかりましたが、単独でフォルダ/ファイルと言われると、相手に正しく伝わりません。
> if (fp == NULL && fp2 == NULL){
and条件とor条件は理解していますか?
&& は 両方成立つときに真となる「and条件」です。
fopenで失敗したときの戻り値がNULLなので、このif文は「 0.txtも1.txtもfopenに失敗したとき」と言う意味になります。
「0.txtだけ失敗した」や「1.txtだけ失敗した」場合にはこのif文は成り立ちません。
また、エラー処理をしているのかと思えば
> printf("\n");
と、改行文字を表示しているだけです。何を意図しているのでしょうか?
> }
> printf("\n");
> }
> fclose(fp);
> fclose(fp2);
ここのprintfは期待しているものですか?
元の例では、1.txtが終ったときに、私のwhile→ifの変更では2行置きに改行が表示されます。
1.txtには行末の改行文字があるので、ただ継げるだけなら必要無いのではないでしょうか。
c言語はまだかなりの初心者でして
質問するのも難しかったのですが
私の誤りのあった質問の意図を理解していただき
ありがとうございます。
ご回答の内容を参考に
いろいろな方法を考えてみたいと思います。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バイナリファイルをテキストフ...
-
0x00をファイル出力
-
営業秘密の漏洩について
-
ExcelVBA サーバーの(共有フォ...
-
ファイル形式またはファイル拡...
-
C言語初心者の質問失礼します。
-
Microsoft VBAで2GBを超えるフ...
-
OLE又はDDEを使うVISUAL BESIC...
-
VB6.0で作ったプロジェクトが起...
-
ファイルの結合
-
実行ファイルと実行モジュール...
-
フルパスから最後のディレクト...
-
CSVファイルへの保存の際、デー...
-
jarの開き方を教えてください。
-
Access クエリ実行が急に非常に...
-
VBAにてEXCEL以外のファイル(テ...
-
テキストファイルの最終行を削...
-
バッチで118項目のCSVを処理し...
-
COBOLのファイル出力
-
VB.NETで他のプロジェクトで作...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バイナリファイルをテキストフ...
-
テキストファイルの行数を取得...
-
fgetsで2行目から文字化け
-
ファイル内のデータを1行削除...
-
fopen(書き込みモード)でファイ...
-
【VB.Net】バイト型配列に読み...
-
改行までの一文字ずつのファイ...
-
【C言語】テキスト読み込みの行...
-
テキストファイルの先頭への文...
-
ファイルサイズ指定し、ファイ...
-
VBSで指定行に挿入
-
winsock recvでの文字化け
-
0バイトファイルの作成
-
C言語 バイナリファイルの読み...
-
freadでファイルを読み込んだ際...
-
C言語の質問です。クイズをテ...
-
fopenで開いたファイルのサイズ...
-
書き込んだファイルに改行が入...
-
EOF判定されない
-
続jファイルに文字列を書く
おすすめ情報