質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

631閲覧

二つのテキストファイル内のデータを合算するプログラム

aiueo12345

総合スコア41

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2018/12/02 05:01

編集2018/12/02 09:06

前提・実現したいこと

二つのテキストファイル(data1.txtとdata2.txt)内のデータを合算して新たな別のテキストファイル(data3.txt)に出力するプログラムを書きたいと考えています。
具体的に扱うテキストファイルには一行に1データずつ、
[コードネーム] [スコア]
のようにあり、二つのテキストファイル内で同じコードネームのスコアを合計し、そのスコアを新たなテキストファイルに出力します。
例)
data1.txt

0001 19 0013 13 0029 24 0048 9 0052 6 0070 7 0074 34 0149 21 0203 8 0226 1 1129 36 1802 7 2207 9

data2.txt

0048 6 0074 5 0142 22 0326 44

data3.txt

0001 19 0013 13 0029 24 0048 15 0052 6 0070 7 0074 39 0142 22 0149 21 0203 8 0226 1 0326 44 1129 36 1802 7 2207 9

作っているプログラムを以下に示します。

#include <stdio.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp1,*fp2,*fp3; char string1[5],string2[5]; int figure1[3],figure2[3],i,n,a; if(argc!=3) { fprintf(stderr,"エラー\n"); exit (1); } if((fp1=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"エラー:ファイル%sを読み込めませんでした。\n",argv[1]); exit (1); } if((fp2=fopen(argv[2],"r"))==NULL) { fprintf(stderr,"エラー:ファイル%sを読み込めませんでした。\n",argv[2]); exit (1); } fp3=fopen("zaiko_new.txt","w"); fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]=='0') n++; a=4-n; if(a==0) figure1[0]=0; else if(a==1) figure1[0]=string1[3]-'0'; else if(a==2) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10; else if(a==3) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100; else if(a==4) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100+(string1[0]-'0')*1000; fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]!='0') n++; if(n==0) figure1[1]=0; else if(n==1) figure1[1]=string1[1]-'0'; else if(n==2) figure1[1]=string1[1]-'0'+(string1[0]-'0')*10; fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; a=4-n; if(a==0) figure2[0]=0; else if(a==1) figure2[0]=string2[3]-'0'; else if(a==2) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10; else if(a==3) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100; else if(a==4) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100+(string2[0]-'0')*1000; fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; if(n==0) figure2[1]=0; else if(n==1) figure2[1]=string1[1]-'0'; else if(n==2) figure2[1]=string1[1]-'0'+(string1[0]-'0')*10; while((fscanf(fp1,"%s",string1[0])!=EOF)&&(fscanf(fp2,"%s",string2[0])!=EOF)) { if(figure1[0]==figure2[0]) { fprintf(fp3,"%s %d\n",figure1[0],figure1[1]+figure2[1]); fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]=='0') n++; a=4-n; if(a==0) figure1[0]=0; else if(a==1) figure1[0]=string1[3]-'0'; else if(a==2) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10; else if(a==3) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100; else if(a==4) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100+(string1[0]-'0')*1000; fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]!='0') n++; if(n==0) figure1[1]=0; else if(n==1) figure1[1]=string1[1]-'0'; else if(n==2) figure1[1]=string1[1]-'0'+(string1[0]-'0')*10; fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; a=4-n; if(a==0) figure2[0]=0; else if(a==1) figure2[0]=string2[3]-'0'; else if(a==2) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10; else if(a==3) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100; else if(a==4) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100+(string2[0]-'0')*1000; fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; if(n==0) figure2[1]=0; else if(n==1) figure2[1]=string1[1]-'0'; else if(n==2) figure2[1]=string1[1]-'0'+(string1[0]-'0')*10; } else if(figure1[0]<figure2[0]) { fprintf(fp3,"%s %d\n",figure1[0],figure1[1]); fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]=='0') n++; a=4-n; if(a==0) figure1[0]=0; else if(a==1) figure1[0]=string1[3]-'0'; else if(a==2) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10; else if(a==3) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100; else if(a==4) figure1[0]=string1[3]-'0'+(string1[2]-'0')*10+(string1[1]-'0')*100+(string1[0]-'0')*1000; fscanf(fp1,"%s",string1); i=0; n=0; while(string1[i++]!='0') n++; if(n==0) figure1[1]=0; else if(n==1) figure1[1]=string1[1]-'0'; else if(n==2) figure1[1]=string1[1]-'0'+(string1[0]-'0')*10; } else if(figure1[0]>figure2[0]) { fprintf(fp3,"%s &d\n",figure2[0],figure2[1]); fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; a=4-n; if(a==0) figure2[0]=0; else if(a==1) figure2[0]=string2[3]-'0'; else if(a==2) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10; else if(a==3) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100; else if(a==4) figure2[0]=string2[3]-'0'+(string2[2]-'0')*10+(string2[1]-'0')*100+(string2[0]-'0')*1000; fscanf(fp2,"%s",string2); i=0; n=0; while(string2[i++]!='0') n++; if(n==0) figure2[1]=0; else if(n==1) figure2[1]=string1[1]-'0'; else if(n==2) figure2[1]=string1[1]-'0'+(string1[0]-'0')*10; } } fclose(fp1); fclose(fp2); fclose(fp3); }

発生している問題・エラーメッセージ

上のプログラムをdata1.txtとdata2.txtについて実行してみたところ(コンパイルは通りました)、
比較部分が繰り返されることなく終わってしまいました。
また読み込み状況を確認してみたところ、
string1=0001
a=1
figure1[0]=1
string1=19
n=5645
figure1[1]=1600061541
string2=0048
a=4
figure2[0]=48
string2=6
n=5661
figure2[1]=0
となっており、charで読み込んだ文字列を数字にした時の桁数が正しく読み込めていませんでした。

どのように変更すれば上手く実行できるでしょうか。

大変長いプログラムで申し訳ないのですが、回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

なんか、凄く冗長なので、途中でギブアップ。

で、気づいた範囲で、、。

データの読込みを fscanf(fp1,"%s",string1) で行っていますが、これだと一行まとめて読み込む事になります。従って最初の読込み自体が、ダメって感じですが、違います? fsanf()を使うならば、fscanf(fp1, "%d %d", &data1, &data2) では読み込めないでしょうか? (動作未確認) または、一行読み込んだ後に、空白で分割ですね。(この場合、fscanf()でなく、fgetf()の方が良いかと)

あとは、同じコードの繰り返しが多いので、関数にまとめるとかできないでしょうか?

もう一つ、fscanf() の戻り値は、読み込んだ数です。
EOFと比較しても無意味です。(比較するなら、0 (読込みデータ無し) と)
なんか、この間違い多いですね。

気付いた範囲で。

投稿2018/12/02 12:34

編集2018/12/02 13:54
pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2018/12/02 16:07

『fscanf(fp1,"%d%d",&a,&b);』でも上手くいきました! こんなに簡単に読み込めたなんてびっくりです。 fscanfの戻り値については、fgetcとごちゃごちゃになっていました。 これらを踏まえて書き直したプログラムが以下です。 ``` #include <stdio.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp1,*fp2,*fp3; char c; int a[3],b[3]; if(argc!=3) { fprintf(stderr,"エラー\n"); exit (1); } if((fp1=fopen(argv[1],"r"))==NULL) { fprintf(stderr,"エラー:ファイル%sを読み込めませんでした。\n",argv[1]); exit (1); } if((fp2=fopen(argv[2],"r"))==NULL) { fprintf(stderr,"エラー:ファイル%sを読み込めませんでした。\n",argv[2]); exit (1); } fp3=fopen("zaiko_new.txt","w"); fscanf(fp1,"%d %d",&a[0],&a[1]); fscanf(fp2,"%d %d",&b[0],&b[1]); while((fscanf(fp1,"%d%d",a[0],a[1])==2)&&(fscanf(fp2,"%d%d",b[0],b[1])==2)) { if(a[0]==b[0]) { fprintf(fp3,"%d %d\n",a[0],a[1]+b[1]); fscanf(fp1,"%d %d",&a[0],&a[1]); fscanf(fp2,"%d %d",&b[0],&b[1]); } else if(a[0]<b[0]) { fprintf(fp3,"%d %d\n",a[0],a[1]); fscanf(fp1,"%d %d",&a[0],&a[1]); } else if(a[0]>b[0]) { fprintf(fp3,"%d %d\n",b[0],b[1]); fscanf(fp2,"%d %d",&b[0],&b[1]); } } if((fscanf(fp1,"%d%d",a[0],a[1]))!=2) { while((fscanf(fp2,"%d%d",b[0],b[1])==2)) fprintf(fp3,"%d %d\n",b[0],b[1]); } else if((fscanf(fp2,"%d%d",b[0],b[1]))!=2) { while((fscanf(fp1,"%d%d",a[0],a[1])==2)) fprintf(fp3,"%d %d\n",a[0],a[1]); } fclose(fp1); fclose(fp2); fclose(fp3); } ``` コンパイルは通りましたが、実行するとセグメントエラーと出ました。 最後のwhile文の繰り返し条件に問題があると思うのですが、どのように繰り返せばよいでしょうか。 fp1とfp2どちらともについて読み込めるデータがなくなったときは、読み込めるデータが残っている方のデータをすべてfp3に出力して終わりたいと考えています。
pepperleaf

2018/12/03 13:54

詳しく見ていませんが、、、 while() 内の fscanf() 正しいですか? > while((fscanf(fp1,"%d%d",a[0],a[1])==2)&&(fscanf(fp2,"%d%d",b[0],b[1])==2)) ポインタになっていません。 また、a[] b[] 配列にする必要あるのでしょうか? 質問文は編集できます。 インデント無しでは読みにくいです。
guest

0

・1行分読み込む
・スペースで文字列分ける
・それぞれを整数変換
・ファイルが尽きるまで繰り返し

という手順で実装していきましょう


私がするなら、
・1行分読み込む
fgets 関数
・それぞれを整数変換
strtol関数

を使って実装しますねー

投稿2018/12/02 05:23

編集2018/12/02 09:16
y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aiueo12345

2018/12/02 08:04

ご回答ありがとうございました。 大変申し訳ないのですが、複数の通報があったようなので、この質問では質問しきれていない部分も含めて再度質問しなおそうと思います。 せっかく回答していただいたのにも関わらず、このような結果になってしまい、すみません。 この回答も役立てながら頑張ります。
aiueo12345

2018/12/02 08:07

と思ったのですが、質問の削除の仕方がわからなかったため、この質問を1から編集することにします。
tatsu99

2018/12/02 12:43

一旦、この質問をクローズして、新たに質問されてはいかがですか。 今回は、そのほうが良いと思います。
aiueo12345

2018/12/02 15:37

y_waiwai様、回答編集ありがとうございます。 strtol関数についてはまだやっておらず、またpepperleaf様の回答のfscanfの用法が使えたのでそちらでやってみたいと思います。
aiueo12345

2018/12/02 15:41

tatsu99様、クローズというのはベストアンサーを決めてしまって解決済みにするということでしょうか。 私も質問を1からし直すべきだろうと思ったのですが、その方法は思いつかず、編集後新たな回答もいただいたため、今回はこのままにしておこうと思います。 ご意見ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問