ファイルaとファイルbから1行ずつ順にデータを読み込んでその行の大小関係を比較して、小さい方の行(同じ大きさなら両方)をファイルcに書き込むプログラムを作成したいと考えています。
そこで、以下のようなソースコード(途中まで)を書いてみました。
#include <stdio.h>
main()
{ FILE *fpa,*fpb,*fpc;
char fpa_data[200],fpb_data[200];
fpa=fopen("filea.txt","r");
fpb=fopen("fileb.txt","r");
fpc=fopen("filec.txt","a");
fscanf(fpa,"%s\n",fpa_data);
fscanf(fpb,"%s\n",fpb_data);
x = strcmp( fpa_data,fpb_data);
if(x<0)
fprintf(fpc,"%s\n",fpa_data);
else if(x=0)
fprintf(fpc,"%s\n%s\n",fpa_data,fpb_data);
else
fprintf(fpc,"%s\n",fpb_data);
}
このソースコードですと、最初の1行目のみが正しく実行されると思いますが、これを2行目以降の行に対しても行うようにするには、どのようにすればよいでしょうか?
ご回答宜しくお願いします。
No.4ベストアンサー
- 回答日時:
>if (fgets(buff_a, BUFFSIZE, fp_a) == NULL) break;
>ですと、行の終わりでwhileループから抜け出してしまい、
>1行目しかファイルcに書き込まれないような気がします。
いえいえ。
fgetsはファイルから1行読み込んで、その文字列を返します。
もしファイルの終端までいったら、NULLを返します。
>あと、ファイルの一方が先に終端までいった際には、もう一方の
>ファイルの残りの行全てをファイルcに書き出したいのですが、
>どのようにすればいいでしょうか?
各ファイルが終端にいったかどうかをあらわすフラグを
用意すればいいでしょう。
たとえばこのように(a_is_endとb_is_end)。
#include <stdio.h>
#include <string.h>
int main(void)
{
#define BUFFSIZE 256
char buff_a[BUFFSIZE];
char buff_b[BUFFSIZE];
FILE *fp_a = fopen("a", "r");
FILE *fp_b = fopen("b", "r");
FILE *fp_c = fopen("c", "w");
int a_is_end = 0;
int b_is_end = 0;
while (1) {
if (!a_is_end && fgets(buff_a, BUFFSIZE, fp_a) == NULL)
a_is_end = 1;
if (!b_is_end && fgets(buff_b, BUFFSIZE, fp_b) == NULL)
b_is_end = 1;
if (a_is_end && b_is_end) break;
if (!a_is_end && !b_is_end) {
switch (strcmp(buff_a, buff_b)) {
case -1:
fprintf(fp_c, "%s", buff_a);
break;
case 0:
fprintf(fp_c, "%s%s", buff_a, buff_b);
break;
case 1:
fprintf(fp_c, "%s", buff_b);
break;
}
}
if (b_is_end) fprintf(fp_c, "%s", buff_a);
if (a_is_end) fprintf(fp_c, "%s", buff_b);
}
fclose(fp_a);
fclose(fp_b);
fclose(fp_c);
return 0;
}
この回答への補足
ご回答ありがとうございます。
>いえいえ。 fgetsはファイルから1行読み込んで、その文>字列を返します。 もしファイルの終端までいったら、N
>ULLを返します。
なるほど、fgetsは文末まで順に読み込んでくれるのですね。fscanfは1行読み込んだら終わってしまいますので、私が最初に考えたプログラムではどうすることもできませんね。(笑)
>各ファイルが終端にいったかどうかをあらわすフラグを
>用意すればいいでしょう。
>たとえばこのように(a_is_endとb_is_end)。
そう考えたらよかったんですね。恐らく自分ひとりで考えていたら、そういう発想はできなかったと思います。
プログラムの方も先ほど実行したところ、きちんと動作しました。どうもありがとうございました。
Cをはじめて1ヶ月の初心者ですので、これからもお世話になることがあるかもしれませんが、その時には、宜しくお願い致します。(m_m)
No.7
- 回答日時:
> >> result = stata ? 1 : -1;
>の文はどういったことをしているのでしょうか?
まず、この if文(else)に入る条件は ファイルAまたは ファイルBのいずれかが既にファイルの終端まで達している場合です。
stata 及び statbは fgetsの戻り値を格納する変数で、ファイルが終端に達していれば NULLが入ってますよね。
result = stata ? 1 : -1 はご存じかもしれませんが、三項演算子で、stataが 0(NULL)ではないとき、resultに 1を格納、0以外の時は -1を格納します。つまり、stata (ファイルA)にデータが残っている場合は 1を入れ、stataが空の時(ファイルBにデータが残っているとき)は -1を入れます。
...とここまで書いて、バグに気が付きました^^;)。
---
int stata = 1, statb = 1;
while (1) {
if (stata) stata = fgets (fpa_data, 200, fpa);
if (statb) statb = fgets (fpb_data, 200, fpb);
if (stata && statb) {
result = strcmp (fpa_data, fpb_data);
} else if (stata || statb) {
result = stata ? 1 : -1;
} else {
break;
}
if (result <= 0) fprint (fpc, "%s\n", fpa_data);
if (result >= 0) fprint (fpc, "%s\n", fpb_data);
}
---
#はづかしい...
No.6
- 回答日時:
ちょっと注意。
strcmp(a, b)の戻り値は、
・a < b のとき ゼロより小さいint (-1とは限らない)
・a > b のとき ゼロより大きいint(1とは限らない)
・a == b のとき 0
ですので、No.4のように-1、1と比較するのは
よくないでしょう。
(自分で書いといてなんなんですが)
この回答への補足
度々ありがとうございます。
私の処理系では-1,0,1でも問題ありませんでしたが、念のために変えといた方がいいですね。
if文を使ってなら、
int x;
x=strcmp(buff_a,buff_b);
if(x<0);
・・・
と書けますが、
case文中で不等号を含む条件分岐は書けるのでしょうか?(多分無理だと思いますが・・・)
No.5
- 回答日時:
締め切られていないようなので、参考までに自分のソースを改造して要求仕様に合わせてみました。
---
int stata = 1, statb = 1;
while (stata || statb) {
if (stata) stata = fgets (fpa_data, 200, fpa);
if (statb) statb = fgets (fpb_data, 200, fpb);
if (stata && statb) {
result = strcmp (fpa_data, fpb_data);
} else {
result = stata ? 1 : -1;
}
if (result <= 0) fprint (fpc, "%s\n", fpa_data);
if (result >= 0) fprint (fpc, "%s\n", fpb_data);
}
---
この回答への補足
度々ありがとうございます。
早速、質問させていただきたいのですが、
stataは普通の変数と考えれば宜しいのでしょうか?
それとも、何か特別な意味があるのでしょうか?
また、
>> result = stata ? 1 : -1;
の文はどういったことをしているのでしょうか?
いままで、こういった文を見たことがないもので・・
低レベルな質問と思いますが、宜しければご回答をお願いします。
No.3
- 回答日時:
あ、いきなり間違いに気が付きました^^;)。
while (stata && statb) {
->
while (stata || statb) {
でした。
No.2
- 回答日時:
若干条件があいまいなので、いくつか仮定して書いてみました。
ファイルA, ファイルBは昇順にソート済である。
同じ行同士を比較するのではなく、AとBのファイルをマージしながら昇順に書き込む。
fopen以降の例
---
stata = fgets (fpa_data, 200, fpa);
statb = fgets (fpb_data, 200, fpb);
while (stata && statb) {
if (stata && statb) {
result = strcmp (fpa_data, fpb_data);
} else {
result = stata ? 1 : -1;
}
if (result <= 0) {
fprint (fpc, "%s\n", fpa_data);
stata = fgets (fpa_data, 200, fpa);
} else {
fprint (fpc, "%s\n", fpb_data);
statb = fgets (fpb_data, 200, fpb);
}
}
---
#未検証です。
ご回答ありがとうございます。
>ファイルA, ファイルBは昇順にソート済である。
>同じ行同士を比較するのではなく、AとBのファイルをマー>ジしながら昇順に書き込む。
せっかく回答して頂いて申し訳ないのですが、ファイルA
とファイルBは昇順にソート済みではないのです。私としましては、1行1行の大きさを調べながらファイルに書き込んでいくといったプログラムを作成したいと考えておりました。
誤解を与える表現で申し訳ございませんでした。
No.1
- 回答日時:
とりあえずどっちかのファイルの終端までいったら
そこでおしまいってことにするとこんな感じでしょうか。
#include <stdio.h>
#include <string.h>
int main(void)
{
#define BUFFSIZE 256
char buff_a[BUFFSIZE];
char buff_b[BUFFSIZE];
FILE *fp_a = fopen("a", "r");
FILE *fp_b = fopen("b", "r");
FILE *fp_c = fopen("c", "w");
while (1) {
if (fgets(buff_a, BUFFSIZE, fp_a) == NULL) break;
if (fgets(buff_b, BUFFSIZE, fp_b) == NULL) break;
switch (strcmp(buff_a, buff_b)) {
case -1:
fprintf(fp_c, "%s", buff_a);
break;
case 0:
fprintf(fp_c, "%s%s", buff_a, buff_b);
break;
case 1:
fprintf(fp_c, "%s", buff_b);
break;
}
}
fclose(fp_a);
fclose(fp_b);
fclose(fp_c);
return 0;
}
この回答への補足
レスありがとうございます。
少し、分からないことがありますので、質問させていただきたいのですが、
if (fgets(buff_a, BUFFSIZE, fp_a) == NULL) break;
ですと、行の終わりでwhileループから抜け出してしまい、
1行目しかファイルcに書き込まれないような気がします。
あと、ファイルの一方が先に終端までいった際には、もう一方のファイルの残りの行全てをファイルcに書き出したいのですが、どのようにすればいいでしょうか?
ご回答宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# pythonのファイルの並びでの読み込みとリストについて 4 2022/04/13 03:52
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- その他(プログラミング・Web制作) Fortranでの出力ファイル 2 2023/03/21 21:25
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- Java 動かなくなったのでJavaソースを手直しお願いします。 2 2022/04/30 05:35
- その他(プログラミング・Web制作) Python - Excel で Webからデータを連続取得したいのですが エラーが出ます 1 2023/07/06 20:08
- その他(プログラミング・Web制作) データ解析ソフトRでのファイル入力read.csvがエラーになります 7 2022/03/27 22:11
- Visual Basic(VBA) vbaのループ処理について 6 2022/05/06 15:35
- アプリ ダウンロードしたファイルを、内部ストレージのdataの中にあるアプリの中に移動させたいのですが、ファ 1 2023/03/15 16:06
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エラーがわかりません、、
-
ファイルへの書込み処理が異常...
-
c言語 ファイルから数字を読み...
-
ファイルに行番号を追加
-
c言語でのfscanfについて
-
ガンマ変換 C言語でプログラ...
-
ファイルの特定行の抽出
-
ファイル読み込み EOF 判定
-
Cで文字列の分割
-
2÷3などの余りについて
-
C言語で%を使わない余りの出し方
-
比較回数と交換回数表示について
-
信頼区間の1.96や1.65ってどこ...
-
nCmの関数
-
複数桁10進数の*桁目だけを抽出...
-
Notepad++の関数リスト表示の変...
-
C言語のfor文です。 繰り返しの...
-
break文でループを一気に抜ける...
-
正負を反転させて出力するプロ...
-
#define _CRT_SECURE_NO_WARNIN...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
C言語でファイル読み書きを早く...
-
fopenでファイル名に、変数を使...
-
複数ファイルの同時読み込みの...
-
fgets( ) の返り値は何?
-
テキストファイル内に対して, ...
-
ファイルへの書込み処理が異常...
-
C言語にてXMLファイルから任意...
-
ファイル出力で改行を入れたい!
-
C言語でセグメンテーションエ...
-
エラーがわかりません、、
-
ガンマ変換 C言語でプログラ...
-
自己相関関数を求めるプログラ...
-
VisualStudioでのファイルの入...
-
同時にファイル読み込み 書き込み
-
c言語 ファイルから数字を読み...
-
大量の入力ファイルを扱うとき...
-
ファイルが読み込めない・・・
-
【C言語】ファイルを読み込んで...
-
a*(1-exp(-bx))+cの近似の方法
おすすめ情報