ご質問させていただきます。
これは、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);

このQ&Aに関連する最新のQ&A

A 回答 (21件中11~20件)

こんにちは。

itohhといいます。

>130..344
>500..600
>700..999
>800..850
この場合は、どのように出てほしいのでしょうか?

A(130)
B(344)
A(500)
B(600)
A(700)
A(800)
たぶん、上記のようになって終わってしまうと言うことですよね?

この後、
B(999)
B(850)
と出てほしいのでしょうか?

それとも
A(130)
B(344)
A(500)
B(600)
A(700)
B(999)  <--追加
A(800)
B(850)  <--追加
と出てほしいのでしょうか?

この回答への補足

ご回答ありがとうございます。
この場合は
A(130)
B(344)
A(500)
B(600)
A(700)
B(999)  <--追加
A(800)
B(850)
というふうに出したい んです。つまり、fin2の ファイルには上から順に一行に二つ数字があるんですけど、それをaとbというふたつの配列に読み込んでますよね?それを一行分ずつ上から順に出力したいんです。つまり、配列に格納された数字の大きさを中心に考えるのではなくて、一行分ずつ出力していきたいんです。重ねがさね恐縮ですが、アドバイス頂けたら嬉しいです。

補足日時:2002/02/12 01:20
    • good
    • 0

こんにちは。

itohhといいます。

>一部データ中には途中で減少する箇所があるんです
finファイルも全て読み込んでしまうことはできないのですか?
全て読み込んだ後ならば、簡単に出来ると思いますよ。

やっぱり、減少するところも含めて順番に出力したいのですよね?
もし、順番は気にしないのでしたらば、fin2ファイルの配列をソート(並べ替え)
した後にfinファイルと比較するという手もあります。

どちらもだめでしょうか?

この回答への補足

御回答ありがとうございます。
全部読み込んでいくことはできるんですが、たとえば
130..344
500..600
700..999
800..850
みたいな感じで並んでるところがあったら、それ以降すべての出力がAのみに
なっちゃうんです。
 ifの処理をwhile()からはずして書くということなんでしょうか?

補足日時:2002/02/11 21:59
    • good
    • 0

 うまく行ってよかったですね。


 単調増加でない場合は一度”C”を出力してしまっている所に
”A”、”B”を出力することになるので、そう言うことを想定
しないと言うことです。
 一度書き出した箇所に重ねて出力することも可能ですが、書き
出す前に全て見て調べておいて小さい順に並べた後出力すると言う
ことも考えられます。処理は多少煩雑になると思います。
    • good
    • 0
この回答へのお礼

御回答ありがとうございました。おかげさまでたすかりました!!
あと、もう一歩です。
減少の時の謎さえとければ・・・・・。
がんばってみたいとおもいます。

お礼日時:2002/02/11 22:15

こんにちは。

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);
}
    • good
    • 0
この回答へのお礼

度々、お返事ありがとうございます。
フラグを使わない方法もやってみました!!なんか、使い慣れてないんで
こっちの方がピンと来ます。両方わかればいいんですが・・・。
ところで、各々の配列が単調増加ならば問題ないんですが、一部データ中には途中で減少する箇所があるんです・・・・・。
その時って、if文の中にさらにif文を書いて・・・・みたいにやってみたんですが、エラーの嵐になってうまくいかないんです・・・。
こういう場合って非常に難しくなるんでしょうか?

お礼日時:2002/02/11 18:59

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");
}

大変そうですが頑張ってください。
    • good
    • 0
この回答へのお礼

御回答ありがとうございます。
これで、やってみたらうまくいきました。
フラグっていうのは使ったことないんでしたが、これを機にもっと
勉強してみようと思います!!
ところで、これは各々が単調増加する場合でしたが、途中で
aもしくはbが減少した場合は、だめですよね?
減少するという場合も考えられるんですが、その時は、
if(n==b[yabuB])
{
}
の中にさらに
if文とかで、条件を分けて、b[yabuB-1]<b[yabuB]の時・・・
みたいにする事って可能なんでしょうか?
かいてはみたもののエラーだらけになっちゃいます。

お礼日時:2002/02/11 18:55

こんにちは。

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の中
の文字が何番目かということを比較したいんです。その場合もこういう風にするんでしょ
うか?なんか実行結果がうまくいかないんで混乱してしまいました。何度も恐縮ですが教
えて頂けたら嬉しいです。

補足日時:2002/02/10 20:41
    • good
    • 0

ANo.#3のtgbです。


申し訳ありません。余計なことなのですが、念のため補足
させていただきます。
a[]とb[]のそれぞれの比較を行うとき、if文で
elseを使わないでください。つなぐと独立な処理に
ならなくなります。(私の示した例ではelseは入れて
いません)
    • good
    • 0
この回答へのお礼

ありがとうございます。
if-elseは使わないんですね!?
ありがとうございました!!!!!!!!!!!1

お礼日時:2002/02/10 17:48

こんにちは。

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ファイルの存在自体は必要ですよね?

補足日時:2002/02/10 17:40
    • good
    • 0

処理内容がよく分かっていないので的確な指摘かどうか分かりませんが、


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++;}
.......

この回答への補足

御回答ありがとうございます。変数をわけてみればいいんですか・・・・。
早速、やってみたいと思います。
ありがとうございました!!!

補足日時:2002/02/10 17:45
    • good
    • 0

こんにちは。

itohhといいます。

すみません、一部ソースを読み違えました。
>まず、このソースはコンパイルエラーになりませんか?
>>for(int i=0; fgets(c,CHARMAX,fin2)!=NULL;i++)
>fgetsの文法が間違っています。
わたしの勘違いでした、ごめんなさい。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qfp = fopen(argy[1], "r");の[1]の意味は

https://oshiete.goo.ne.jp/qa/8940272.html
 の11行目に
fp = fopen(argv[1], "r");の[1]の意味が分かりません。
試したいのですが、ソフトがうまく動きません
 よろしくお願いいたします。

Aベストアンサー

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから入力し実行すると、

argc = 5
argv[0] = "test"
argv[1] = "test1"
argv[2] = "test2"
argv[3] = "3"
argv[4] = "4"

と文字列が入ってきます。

以下はサンプル。

void main( int argc , char *argv[])
{
if( argc < 2 )
{
// パラメータ指定がなかった場合の表示
printf( "test に続けて4つまでパラメータを入力できます\n");
exit(0);
}
if( argc > 5 )
{
 // パラメータが5つ以上あった場合の表示
printf( "5つ以上のパラメータは受け付けません\n");
exit(-1);
}

// 正常ルート
printf( "パラメータの数は%d個ですね?ニヤッ\n", argc-1);
printf( "最初のパラメータは%sでしょ?\n", argv[1]);
printf( "残りはargv[2]以降ですが、面倒なので表示しません\n");
}

と言う具合に、引数を活用できます。argv[0]には、実行ファイル名が入ります。
argc は実行ファイルの名前も含めてカウントされます。

プログラムによっては必要な引数の数が変わりますし、
ユーザーのコマンドラインからの入力ミスなどでパラメータがなかったり、
必要なパラメータが不足していたりしますので、
argcとargvを使って最初にシンタックスエラーチェックをするのが常道です。

実行ファイル名の指定がなく、プログラムが実行されることはないと思われます
から、argcは1以上の値になります。

argc, argvの活用は、
実行コマンドを手打ちで打ち込むコンソール形式でよく用いられる基本的な
アプリケーションの開発手法です。

ご質問の箇所は、
第一パラメータにプログラム内で読み込むファイルのファイル名を指定してるの
でしょう。(よくあります)

しかし、Windowsなどのウィンドウを使用するアプリケーションは、
これとは違っておりますので注意が必要です。
(C言語とは別に、Windowsに特化した開発ノウハウの勉強が必要です)

Windows系で上記の様な基本的なプログラムを作成する場合は、
プロジェクトの作成時に(VisualStudioなどで)コンソールアプリケーション
を選んで作成します。実行時にコンソールが開きます。

Linuxの場合は、コンソールがデフォルトになっているでしょうから、
(特殊な設定がなければ)そのまま作成できます。

テキストエディタでソースを記述し、gcc などでコンパイルします。
実行形式ファイルが出来ていれば、想定どおりの動作をするでしょう。

ファイルの読み込みが出来るようになったら、
ファイルの内容を書き換えて保存したり、
ファイル名を変えたり、
ディレクトリ内のファイルを全て表示したり、
ファイル内に含まれる文字列を検索し、該当するファイルをリストしたりなど、

有用なサンプルプログラムを沢山作って練習します。

ファイルを読み込む先は、char型の配列でバイトサイズのメモリーとして確保
します。メモリーと変数の関係を充分に理解することをお勧めします。
殆どのプログラムは、このメモリーの確保やメモリーサイズの計算と格闘する
場合が多くなるからです。

バイナリー形式のファイル(すべてはバイナリー形式として良いのですが)に
ついて理解が深まった後は、
bmpの画像ファイル、wavなどの音声ファイルをあけて、
これの中身を書き換えて遊びます。

特にwavファイルは、音量の変更や周波数フィルタなども掛けれますので、
メモリ、配列、ファイルの関係を(焦らずに)ゆっくり理解するだけで、
今の知識レベルでも面白いことが沢山出来ます。

以上、ご参考に成れば。

前の例題も読みました。

大分苦戦しているようですが、配列については理解が進みましたでしょうか?
お答えしますと、最初のパラメータ文字列が代入されています。

古いC言語の約束でして大変有名なものです。

コマンドラインコンソールから実行ファイル名を書いて、
パラメータをスペースで区切って指定したとします。

このパラメータ文字列が[1]以降に入ります。
例として、"test"と言う名前の実行ファイルがあったとします。

例)> test test1 test2 3 4

このようにコマンドラインから...続きを読む

Qfor(int i = 100, long n = 1; i > n/3i; i++)

for(int i = 100, long n = 1; i > n/3i; i++)
のように、初期設定で型の違う変数を宣言したいんだけど
C++ではこんなふうに2つ以上の型を宣言してはいけないんですか?

Aベストアンサー

,

コンマ演算子の原理です。
forの初期化文で "," で区切れるのは値を返す文だけです。
よってintステートメントもlongステートメントも値を返さないので、この文では使用できません。

というか、むしろ、intステートメントの第2引数としてlongが認識されてしまいます。
外で

int i; long n;

とし

for(i = 0, n = 0; hoge; hoge)

なら可能です。

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む

Qint nII[10] = { 0 }について

久々にCを使ってプログラムを組んでいるのですが、基本的な構文を思い出せず
いくつか教えていただきたく質問させていただきました。

1)配列すべてを初期化するのに、宣言時に

int nII[10] = { 0 };

で大丈夫だった(全ての要素が0で初期化)と記憶しているのですが、間違いないでしょうか?

2)構造体の初期化は

struct tm tm;
memset(&tm, 0, sizeof(struct tm))

で大丈夫でしょうか?

3)構造体の宣言は

typedef struct{
int a;
}HOGE, *LPHOGE;

HOGE st; // <- struct HOGE stと同じ
LPHOGE pst; // <- struct HOGE* pstと同じ

で問題ないでしょうか?

以上、3つ質問になって申し訳ないのですが、よろしくお願いします。

Aベストアンサー

1)OK
2)たぶんOK
3)HOGEという名前の構造体はない(当該の構造体には名前がない)ので、
// 以下のコメント記述が誤っています。ただし、

HOGE st;
LPHOGE pst;
という定義そのものはOK

Q&str[n]とpstr + nと&pstr[n]

あるプログラミングの本で

&str[n]
pstr + n
&pstr[n]

は同じだと書いてあり、考えたのですが、
上の二つはstr[n]のアドレスを表しているとしても、
三つ目はstr[n]のポインタのアドレスを表していると思うのですが
どこが間違っているのでしょうか?教えてください。

Aベストアンサー

>本にも突然でてきているのでよくわからないのですが・・・。

よくわからないもの同士が同じかと聞かれても、よくわからないというのが答えです。
本当に、突然出てきているのなら、そんな本は捨てましょう。


人気Q&Aランキング

おすすめ情報