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

こんにちは。

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さんのお力をかしてください!!よろしくお願いいたします。

補足日時:2002/02/10 01:24
    • 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ランキング

おすすめ情報