- ベストアンサー
配列の比較について・・・困ってます・・。
ご質問させていただきます。 これは、fin2というファイルから数値を抜き出し配列に格納して、finの文字列と比較し、その文字列のある場所で配列の数値と比較し、合致したら、ある出力をするというものなんですが、 配列に格納した数値が、 a[1]=[123] b=[234] a[1]=[345] b=[400] というふうに増えていくときは問題ないですが、途中でたとえば a[n]=100 b[n]=400 a[n+1]=300 b[n+1]=358 という風にn+1番目のaより、n番目のbが大きいときに、止まってしまうんです、これをうまく処理して最後まで比較させたいんですが、どうしてもうまくいきません。どなたかたすけてください。やはり、 n==b[yabu]の処理の後になんか書けばいいんでしょうか?長々と申し訳ございませんでした。 if(fin2!=NULL) { int yabu=0; for(int i=0; fgets(c,CHARMAX,fin2)!=NULL;i++) { sscanf(c,"%d%*c%*c%d",&a[yabu],&b[yabu]); fprintf(fout2,"%d::::::::::::::%d:%d\n",yabu,a[yabu],b[yabu]); yabu++; } } int yabu=0; n=0; while(fgetc(fin)!=EOF) { n++; if(n==a[yabu]) { fprintf(fout2,"A "); } else if(n==b[yabu]) { fprintf(fout2,"B "); yabu++;} else {fprintf(fout2,"C "); } } printf("%d\n",yabu);
- みんなの回答 (21)
- 専門家の回答
質問者が選んだベストアンサー
こんにちは。itohhといいます。 もし、固定で良いのでしたら、補足で書かれているように配列に持っておくほうが楽ですね。 char strData1[]={(char)0x90, (char)0x3C, (char)0x40, (char)0x83, (char)0x60, (char)0x80, (char)0x3C, (char)0x00}; : : : fwrite( strData1, sizeof( char ), sizeof(strData1), fout2 ); strlen(strData1)では、最後の0x00を数えてくれません、ですからsizeof(strData1)ですね。 strData1を必要な分だけ用意しておくと良いのではないでしょうか。 strData2,strData3などなど。 こんなとこでしょうか?
その他の回答 (20)
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >一部データ中には途中で減少する箇所があるんです finファイルも全て読み込んでしまうことはできないのですか? 全て読み込んだ後ならば、簡単に出来ると思いますよ。 やっぱり、減少するところも含めて順番に出力したいのですよね? もし、順番は気にしないのでしたらば、fin2ファイルの配列をソート(並べ替え) した後にfinファイルと比較するという手もあります。 どちらもだめでしょうか?
補足
御回答ありがとうございます。 全部読み込んでいくことはできるんですが、たとえば 130..344 500..600 700..999 800..850 みたいな感じで並んでるところがあったら、それ以降すべての出力がAのみに なっちゃうんです。 ifの処理をwhile()からはずして書くということなんでしょうか?
- tgb
- ベストアンサー率78% (32/41)
うまく行ってよかったですね。 単調増加でない場合は一度”C”を出力してしまっている所に ”A”、”B”を出力することになるので、そう言うことを想定 しないと言うことです。 一度書き出した箇所に重ねて出力することも可能ですが、書き 出す前に全て見て調べておいて小さい順に並べた後出力すると言う ことも考えられます。処理は多少煩雑になると思います。
お礼
御回答ありがとうございました。おかげさまでたすかりました!! あと、もう一歩です。 減少の時の謎さえとければ・・・・・。 がんばってみたいとおもいます。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >fin2の配列の中の数字と比較したいのはfinの中の文字そのものというよりもその >finの中の文字が何番目かということを比較したいんです。 これは、finファイルの中から配列(fin2ファイル)の数値の位置のバイトを 抜き出したいのでしょうか? tgbさんの回答とだぶってしまうんですけど、else if文を使うことによって フラグ(k)を使わなくて良いですよ。 int n=0; yabuA=0; yabuB=0; data = fgetc(fin); for(n=0; feof(fin) == 0; n++ ) { if( n == a[yabuA] ) { fprintf(fout2,"A [%c]", data); yabuA++; } else if( n == b[yabuB] ) { fprintf(fout2,"B [%c]", data); yabuB++; } else { fprintf(fout2,"C "); } data = fgetc(fin); }
お礼
度々、お返事ありがとうございます。 フラグを使わない方法もやってみました!!なんか、使い慣れてないんで こっちの方がピンと来ます。両方わかればいいんですが・・・。 ところで、各々の配列が単調増加ならば問題ないんですが、一部データ中には途中で減少する箇所があるんです・・・・・。 その時って、if文の中にさらにif文を書いて・・・・みたいにやってみたんですが、エラーの嵐になってうまくいかないんです・・・。 こういう場合って非常に難しくなるんでしょうか?
- tgb
- ベストアンサー率78% (32/41)
itohhさんの指摘は私も疑問に思いました。 finからのデータについては 出力する文字A、B、Cの合計数をいくつにするかには寄与しますが finの文字データは全く使っていませんので、質問文の内容とは食い違います。 しかし、ANo.#4の補足から質問の内容が違っていたと理解されます。 行いたい処理をまとめますと fin2から読み込んだ数値データを 左側数値nl...その場所(nl文字目)にAを出力 右側数値nr...〃 (nr文字目)にBを出力 上の数値以外.............. Cを出力 となるのでしょうか。そうなら以下のように出来ると思いますが。 ただし、 a,bともそれぞれに単調に大きくなること、 a,bに共通する数値が入らないこと を前提します。 (今回問題になったaとbとの大小関係はクリアされる筈です) int yabuA=0,yabuB=0; int n=0; int k; while(fgetc(fin)!=EOF) { n++; k=1; if(n==a[yabuA]) { fprintf(fout2,"A "); yabuA++; k=0; } if(n==b[yabuB]) { fprintf(fout2,"B "); yabuB++; k=0; } if(k) fprintf(fout2,"C"); } 大変そうですが頑張ってください。
お礼
御回答ありがとうございます。 これで、やってみたらうまくいきました。 フラグっていうのは使ったことないんでしたが、これを機にもっと 勉強してみようと思います!! ところで、これは各々が単調増加する場合でしたが、途中で aもしくはbが減少した場合は、だめですよね? 減少するという場合も考えられるんですが、その時は、 if(n==b[yabuB]) { } の中にさらに if文とかで、条件を分けて、b[yabuB-1]<b[yabuB]の時・・・ みたいにする事って可能なんでしょうか? かいてはみたもののエラーだらけになっちゃいます。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >一文字ずつ読んでいくということはfin内のデータを使ってる >事となんらないんでしょうか? 以下のソースを見ると、fgetcで読み込んだ1バイトの値はどこに格納されるのでしょうか? if文で比較している値は、nとa[yabu]ですよね? nは単純に0から1づつ増えていくカウンタですよね? >while(fgetc(fin)!=EOF) >{ >n++; >if(n==a[yabu]) >{ >fprintf(fout2,"A "); >} もし、finファイルを読み込んで比較したいのなら char data; int yabu=0; int i=0; long a[100]. b[100]; for(i=0,yabu=0; fgets(c,CHARMAX,fin2)!=NULL;i++) { sscanf(c,"%d%*c%*c%d",&a[yabu],&b[yabu]); fprintf(fout2,"%d::::::::::::::%d:%d\n",yabu,a[yabu],b[yabu]); yabu++; } data = fgetc(fin); while(feof(fin) == 0 ) { // a,b配列と比較する for(i=0; i<yabu; i++ ) { if( data == a[i] ) { fprintf(fout2,"A "); break; } if( data == b[i] ) { fprintf(fout2,"B "); break; } } // a,bにヒットしなかった場合 if( i == yabu ) { fprintf(fout2,"C "); } data = fgetc(fin); } こういうことが、やりたいことなのではないでしょうか? インデントするために全角スペースを行の先頭に入れています。
補足
お返事ありがとうございます。 早速やってみました。これだとfinのデータそのものと比較することになりますよね? fin2の配列の中の数字と比較したいのはfinの中の文字そのものというよりもそのfinの中 の文字が何番目かということを比較したいんです。その場合もこういう風にするんでしょ うか?なんか実行結果がうまくいかないんで混乱してしまいました。何度も恐縮ですが教 えて頂けたら嬉しいです。
- tgb
- ベストアンサー率78% (32/41)
ANo.#3のtgbです。 申し訳ありません。余計なことなのですが、念のため補足 させていただきます。 a[]とb[]のそれぞれの比較を行うとき、if文で elseを使わないでください。つなぐと独立な処理に ならなくなります。(私の示した例ではelseは入れて いません)
お礼
ありがとうございます。 if-elseは使わないんですね!? ありがとうございました!!!!!!!!!!!1
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 >そして、こんどはfinファイルを読みます。このfinは半角英字のみが延々と >かかれているファイルで、これを頭から一文字ずつ読んでいって、 >a[0]に格納された数値と一致したなら、 cout<<"A"の処理をし ここの処理がちょっと判らないのですが。 「finの1文字(半角英字)とa[0]に格納された数値を比較する」 と言うことは 「半角英字のasciiコードとa[0]に格納された数値を比較する」 という意味でしょうか? ソースを見る限り >if(n==a[yabu]) >{ >fprintf(fout2,"A "); >} a[yabu]に123が入っているとしたらn(カウンタ)が123までループしたらfprintf文 が実行されるとなっています。 もし、このままでいいのでしたらfinファイルを読み込む意味がないのではないでしょうか? finファイル内のデータをぜんぜん使っていませんよ。
補足
御回答ありがとうございます。 基本的にはそういう処理をしていくんですが、そのfinに入っている、データ(半角英数字)は、4種類あるんですが、それぞれによって、出力を変えたいんです。 でも、一度に考えるとこんがらがるのでとりあえず、今のような書き方にしてるんです。 >finファイル内のデータをぜんぜん使っていませんよ。 一文字ずつ読んでいくということはfin内のデータを使ってる事となんらないんでしょうか?やっぱり、finファイルの存在自体は必要ですよね?
- tgb
- ベストアンサー率78% (32/41)
処理内容がよく分かっていないので的確な指摘かどうか分かりませんが、 a、bの参照用の変数yabuを独立にしてみたらいかがでしょうか? int yabuA=0,yabuB=0; int n=0; while(fgetc(fin)!=EOF) { n++; if(n==a[yabuA]) { fprintf(fout2,"A "); yabuA++; } if(n==b[yabuB]) { fprintf(fout2,"B "); yabuB++;} .......
補足
御回答ありがとうございます。変数をわけてみればいいんですか・・・・。 早速、やってみたいと思います。 ありがとうございました!!!
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 すみません、一部ソースを読み違えました。 >まず、このソースはコンパイルエラーになりませんか? >>for(int i=0; fgets(c,CHARMAX,fin2)!=NULL;i++) >fgetsの文法が間違っています。 わたしの勘違いでした、ごめんなさい。
- itohh
- ベストアンサー率45% (210/459)
こんにちは。itohhといいます。 処理の内容がいまいち判らないのですが。 1.2つのファイルを読み込む。 2.1行の内容はa,bの2つの値が格納され複数行入っているので配列に格納する(fin2ファイル) 3.チェックしたい値が1行に1個入っている(finファイル) 4.3.の値を1つずつ2.の配列のaなのかbなのかをチェックしたい。 これでよいのでしょうか? まず、このソースはコンパイルエラーになりませんか? >for(int i=0; fgets(c,CHARMAX,fin2)!=NULL;i++) fgetsの文法が間違っています。 >sscanf(c,"%d%*c%*c%d",&a[yabu],&b[yabu]); "%d%*c%*c%d"と&a[yabu],&b[yabu]の数があっていません。 fin2ファイルの中のフォーマットはどのようになっているのでしょうか? >while(fgetc(fin)!=EOF) fgetsの文法が間違っています。(読み込んだデータはどこに格納するのでしょうか?) 2つ目のループはfinファイルがEOFまでループしますが、 比較しているのはカウンタ(n)ですよね?これで良いのですか? finファイルのデータは関係ないのでしょうか?
補足
御回答ありがとうございます。コンパイルエラーになりませんよね? びっくりしちゃいました(笑) 処理としては、 fin2ファイルは、 123..234 [英数字の羅列・・](改行) 300..434 [英数字](改行) 523..674 [英数字](改行) 800..934 [英数字](改行)・・・・・ みたいになってて、そこから数字だけをぬきだして、左の数字をa[yabu]に 右の数字をb[yabu]に格納します。 そして、こんどはfinファイルを読みます。このfinは半角英字のみが延々と かかれているファイルで、これを頭から一文字ずつ読んでいって、a[0]に格納された数値と一致したなら、 cout<<"A"の処理をして、・・・というふうにやっています。・・・・とこのままだとfin2の数値が、単純に増加していけば問題ないのですが、途中でb[n]の数字の方がつぎのa[n+1]よりも大きくなってしまった場合そこで止まっちゃうんです。 123..234 [英数字の羅列・・](改行) 300..434 [英数字](改行) 523..1002 [英数字](改行) 800..934 [英数字](改行)・・・・・ とかいうばあい、3行目で止まっちゃうんです。 いろいろ考えたんですが、なんとかここまではこぎつけたものの、こっから 先がわかんないんです・・・・・。 itohさんのお力をかしてください!!よろしくお願いいたします。
- 1
- 2
お礼
どうもありがとうございました。長期間にわたり回答寄せてくださってありがとうございました!!! おかげさまで、いろいろ勉強することができました!!また、わかんないことがでてきたらここで質問してべんきょうしていきたいと思います。 本当にありがとうございました!!