前回「EOF判定されない」で回答、アドバイスしていただいた
a-kumaさん、Haizyさん、inthefloiさん、anisolさん、leaz024さん、cherry-moonさん
本当にありがとうございました。頂いたアドバイスを試行してみましたが、なぜか、ダメでした。(T-T)
環境が悪いのかもしれませんね。

あれから、feof関数を使わずにファイルの終わりを算出して判定するなどの方法を試みましたが、EOF判定だけのために妙に複雑になってしまい、自分でも納得がいかなかったので、再度こちらで皆さんの意見をもらおうと投稿させてもらいました。

今回は質問の仕方を変えて、モジュールの仕様を挙げますので、それから「自分ならこうする」というようなお答えを頂けたらと思っています。
feof関数を使用しても、その他の方法でもなんでもアリです。(^^)

「ファイル一行入力モジュール」(仕様)
1.このモジュールは実行されると「inputfile.txt」から一行だけ(改行まで)読み込み、終了します。次に実行された時は、その次の行を読み込みます。
2.ファイルの終端に達したら、リターンコードに'4'を設定し、終了する。
以上これだけ。(^^;

「inputfile.txt」(仕様)
インプットファイルは、テキストファイルで、一行30バイトの文字列を格納しています。ファイルの総バイト数は不定です。
文字コードは「Shift-JIS」「改行=CR+LF」、ファイルの最後にEOF制御文字を設定しています。

「インプットファイルの内容」

 1行目 AAAAAAAAAABBBBBBBBBBCCCCCCCCC[改行文字]
 2行目 DDDDDDDDDDEEEEEEEEEEFFFFFFFFF[改行文字]
          ・
          ・
          ・
n-1行目 XXXXXXXXXXYYYYYYYYYYZZZZZZZZZ[改行文字]
 n行目 [EOF]

「ここはこうしたらいいんじゃないかな?」的な事でかまいませんので、是非みなさんの意見を聞かせてください。

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

A 回答 (8件)

問題がでそうなところと言うと,[EOF](^Z)を追加しているところと、ファイルのオープン方法でしょうか。




まず、WindowsとかMS-DOS環境の場合は,
fopenを使い,テキストモードにしておけば問題無いように思います。

f=fopen("inputfile.txt","r");
while( fgets(buff,sizeof(buff),f) );
if ( feof(f) )printf("EOF\n");

みたいにするとこちらではEOF検出してます。

a-kumaさんのが仕様に忠実にできていて正しく動きそうですね。
わがままな私はこの仕様に不満があるので書きませんが(笑)


ところでテキストモードですが、元々unixとのライブラリの整合性をとるためのエミュレーションモードみたいなものです。
これは、DOSやWindowsがunixと改行コードが違ったり,EOFコードがあったりしても
同じプログラムで動作するようにしたものですから、
unixはそういう変換は不要でそもそも区別する必要がなく、モードが存在しないのです。

改行等がからむ物はテキストモードにするのが簡単で間違いないですし、そのままunixでも動作させられます。
バイナリモードでオープンしてfgetsで読むとどうなるか等調べないとわからないような物は面倒です(^^;;


また、EOFコードは確かCP/Mかなんかの名残であるもので、本来は不要なコードです。
必要だったのは,ファイルシステムにファイルサイズが存在しないためです。(クラスタ単位でしかわからない)
    • good
    • 0

補足ありがとうございます。

素人ですが、もうちょっと調べてみました。私の前の回答は的外れだったみたいです……。

feof()と[EOF]の組み合わせは使わないほうがいいかもしれません。というのは、feof()で[EOF]を認識させることはバイナリモードではできないようです。またUNIXではfopen()はバイナリモードしかないようで、機種依存的になります。[EOF]のコードを使わず、単純にファイルの終わりをfeof()で調べるのはだめですか?

とりあえず、今まで調べた結果なので間違っているまたは的外れだったらごめんなさい。
    • good
    • 0

私も前回の回答を見たらトホホでした。



29文字+CR+LFの31バイトに確実に固定されていて、ウィンドウズ系以外のOSであるならば、fgetsを使わずに、

char buff[31];
if (fread(buff, 1, 31, fp) < 31)
{
 if (feof(fp))
 {
  rtn_code[0] = '4';
 }
 else
 {
  rtn_code[0] = '8';
 }
}
else
{
 buff[29] = '\n';
 buff[30] = '\0';
}

というような、やり方もあるかなと思います。
    • good
    • 0

こんにちは。



前回は、とろけていてゴメンナサイ。

さて、前回の最後の投稿で、触れたかもしれませんが、「改行=CR+LF」ということなので、これ自身が ”2バイト” 食っていると思います。
ですので、fgetsの第二引数(何文字読み込むか)を第一引数の限界も考慮しつつ、大きくする事が有効ではないかと思います。
【#3の例】
>char buf[1024]
完璧です。
>fgets(buf, sizeof(buf), in) ・・・・
sizeof(buf) が、文句なしの完璧です。さすがッス。こんな感じです。

同時に16進で、監視式によりbufの値を監視してみてください。
動きが変だと、ココでわかると思います。

でわ、失礼します
    • good
    • 0

前回の質問、解決したのか気になって、夜も寝られませんでした(嘘)。

早めに補足を行ってくださいね……。

ところで、
・[EOF]はどのような方法で書きこんでいるのでしょうか。またそのコードは何ですか。
・Windowsベースでのプログラムですか、またはUNIXベースですか。
・単純に[EOF]だけ書きこんだファイルで、fgets(buff, 2, fp) およびfeof(fp)を実行したとき、EOF判定はされますか。(この点は重要かも)

以上お手数ですが補足していただけますか。ちょっと情報が少なすぎますので。

この回答への補足

毎度毎度説明不足でスイマセン(--:

・EOF制御文字は、秀丸エディタのオプションで「保存する時に、EOF制御文字を付加する。」にチェックを入れることでファイルに保存されています。
バイナリエディタで見ると'1A'となっています。
・Windowsベースのプログラムです。
次に、
EOFだけを書き込んだファイルですが、秀丸では文字が記述されていないと保存できずに削除しようとするので、他のバイナリエディタを使用し1Aとだけ書いて保存しました。

それから説明不足がもう二つあります。(ホントすいません)

1.fgetsの第二引数にunsigned long型のlengthという箱を使ってます。
で、このlengthにrecord_lngsをstrtolでlong型に変換して代入しています。

unsigned long length;
char record_lngs[5]; ←これには00020という文字列が格納されています。
char *endptr;
char buf[32756];

length = strtol(record_lngs, &endptr, 10);

if (fgets(buf, length, in) == NULL) {
   if (feof(in)) {
     return 4;
   }
}
こんなかんじで実行しましたが、4は返ってきませんでした。
lengthに入ってるの20じゃダメじゃん!?と、お思いでしょうがなぜかこれでgetは正常に行われます。lengthに1や2を足してgetすると、何も読みこまれなくなります。これも謎ですね。

2.inputfile.txtは1レコード(一行)の大きさが32756バイトです。今回その1レコード(一行)に入っているデータは固定長の20バイトですが、他にも5000や,32756バイト入っている場合もあります。
こんな粗悪な説明でわかりますでしょうか?また何か説明が必要でしたら書き込んでください。(うう、もっと文章力つけとけばよかった)

補足日時:2001/10/31 14:07
    • good
    • 0

ん~、何がうまくいかないのか、よく分からんです。



と、いうわけで、提示された仕様に忠実にデータを抱えてしまっていますし、
エラーチェックもしてませんが、こんな感じの関数で良いんじゃないですか?

#include <stdio.h>

int xxx()
{
  char buf[1024];
  static FILE* in = NULL;
  if (in == NULL) {
    in = fopen("inputfile.txt", "r");
  }
  if (fgets(buf, sizeof(buf), in) == NULL) {
    if (feof(in)) {
      return 4;
    }
  }
  return 0;
}

/* テストコード */
int main()
{
  int ret;
  int i;
  for (i = 0 ; (ret = xxx()) == 0 ; ++i) { printf("%d\n", i); }
  printf("ret = %d\n", ret);
  return 0;
}
    • good
    • 0

訂正!回数間違えました!!



従ってfgetsは4回行われますが、3回目で1文字以上を格納し、かつ、EOFを検出しています。つまりfgetsはNULLを返していません。このときにfeofを実行すれば「EOF検出」となるのですが、4回目を実行したためにfeofは「非EOF検出」となっています。

以上です(汗)
    • good
    • 0

前回の質問を今さら見ました。



まず、fgetsの使い方が間違ってます。第2引数は読みとる文字数+1なんです。つまり、テキストモードで開いた場合、20文字+改行文字で21キャラですから「22」以上を指定しなければなりません。これは、読みとった文字列の最後にナル文字を格納するためです。
従ってfgetsは5回行われますが、4回目で1文字以上を格納し、かつ、EOFを検出しています。つまりfgetsはNULLを返していません。このときにfeofを実行すれば「EOF検出」となるのですが、5回目を実行したためにfeofは「非EOF検出」となっています。

対策としては、充分な格納領域buffと読みとり文字数を引数にして、最後の行に改行があることを信じないで、毎回EOF判定する。

こんなとこでしょうか?
    • good
    • 0

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

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

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

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

Q化合物の同義語について

こんにちは。製薬企業の特許関係の仕事をしています。
仕事上、多量の文献を調査するのですが、その際同義語も含めて調査する必要があります。この、同義語を調べるのに苦労しています。
同義語を調べるのに便利な本、又はWEBページはありますでしょうか?
どなたか知っていたら教えてください。

宜しくお願い致します。

Aベストアンサー

こちらで引いてみたら,うまくいくかもしれません.
http://homepage1.nifty.com/k_funa/aiueo2.html

他にも,便利な情報がこちらに出ています.
http://www.chem-station.com/
http://chemnews.cambridgesoft.com/index.cfm?language=j

Qchar *name1[4] とchar name2[][4] の違いについて

C言語のことで質問があります。

char *name1[4]は
char *name1[4] = {"abcdefghi","jkl","l","mn"};
と宣言でき,ポインタを4つ確保した形となりました。

char name2[][4]は
char name2[][4] = {"abc","def","ghi","jkl","mno","pqr","stu","vwx"};
と4文字以内の文字列を初期化した数だけ確保した形となりました。

この結果からchar *name1[4]の意味は,char name2[][4]ではなくchar name2[4][]に近いと思いました。
しかし,char name2[4][]ではポインタを4つ確保した事にはならないみたいでコンパイルが通りません。
*name1[4]では4つのポインタを確保できるのに~と思ってしまいます。

ポインタと配列は別物と考えるべきなのでしょうか?
訳の分からない質問かもしれませんが,
何卒ご指導いただくようよろしくお願いします。

Aベストアンサー

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり、この場合のa1は、
変数ではなく、定数のようなものなのです。

複合的なケースについて見てみましょう。
char **q1; ポインタへのポインタ
 q1,*q1,**q1,q1[0],*q1[0],q1[0][0] のいずれも変数として
 扱うことができます。(値を代入することが文法的に許されます。
 ただし、実行時にはアクセス違反になる場合もあります。)
char q2[4][4]; 二次元配列
 q2,q2[0]は変数として扱うことができません。q2[0][0]のように
 して、初めて変数として扱えるようになります。
char *q3[4]; ポインタの配列
 q3は変数として扱うことができませんが、q3[0],*q3[0],q3[0][0]
 はいずれも変数として扱うことができます。
 なお、この定義は char *(q3[4]); とした場合と全く同じ意味です。
char (*q4)[4]; 配列へのポインタ
 q4,(*q4)[0],q4[0][0]はいずれも変数として扱うことができます。
 しかし、*q4,q4[0]は変数として扱うことができません。

char *name1[4]; と char name2[4][]; は確かに似ています。しかし
違うところもあります。それは、name1[0] が変数として扱えるのに
対し、name2[0] には値を代入できないという点です。(データの
具体的な構造については、inthefloiさんが書いておられる通りです。
> char name2[4][]ではポインタを4つ確保した事にはならないみたい
というのも、全くその通りで、配列の定義では、ポインタ変数の領域
を確保する余地はないのです。

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり...続きを読む

Qロッケン・ベーレン・アウスレーゼと貴腐ワイントは同義語ですか?

ドイツ・ワインの分類/等級の説明で、しばしば「トロッケン・ベーレン・アウスレーゼ(貴腐ワイン)」の如く、両者が同義語であると受け取れる解説を見かけますが、両者は厳密な定義上も100%同義語なのでしょうか?
若しも何らかの差異があるならば、違いを解説戴ければ幸いです。

Aベストアンサー

「称号付き上級ワイン」と訳される最上級クラスは、次の6つです。
肩書きはブドウの糖度で決まります。

「トロッケンベーレンアウスレーゼ」は、「貴腐菌がついて干しブドウ状になったブドウ粒から造る最高級の極甘口ワイン」と一般的に解されますが、意味は、「乾いた果粒を選り摘んだ」ということで、必ずしも貴腐ワインということではありません。
たいていのブドウ品種は、貴腐化なくして高糖度にはできないと言われていますが、ごく限られた品種では、貴腐によらずして比較的容易に高糖度に達することができます。
トロッケンというのは、干からびている、という意味です。
但し、単に“トロッケン”と表示されているものは、「辛口」という意味なので注意が必要です。


「アイスヴァイン」は、樹の上で完熟し、凍りついたブドウから造る甘口ワイン。

「ベーレンアウスレーゼ」は、過熟したブドウ粒から造る極甘口ワインですが、貴腐ブドウもブレンドされます。

「アウスレーゼ」は、よく熟したブドウ房から造るワイン。

「シュペトレーゼ」は、通常よりも7日以上遅摘みのブドウから造るワイン。

「カビネット」は、普通のブドウから造るワインで、最も辛口&低アルコール。

「称号付き上級ワイン」と訳される最上級クラスは、次の6つです。
肩書きはブドウの糖度で決まります。

「トロッケンベーレンアウスレーゼ」は、「貴腐菌がついて干しブドウ状になったブドウ粒から造る最高級の極甘口ワイン」と一般的に解されますが、意味は、「乾いた果粒を選り摘んだ」ということで、必ずしも貴腐ワインということではありません。
たいていのブドウ品種は、貴腐化なくして高糖度にはできないと言われていますが、ごく限られた品種では、貴腐によらずして比較的容易に高糖度に達すること...続きを読む

Q[VC++][MFC][SDI]ダイアログコントロールもしくわツールバー!!詰まってます!!

現在VC++6.0でMFCを使いSDIのプログラムを作っているのですが、フォームにダイアログバーを張っています。

これをツールバーのように自由に動かしたり、左右上下にドッキングさせたり。
これって実現可能でしょうか?

色々ためしてみたんですが無理でした。
やっぱ不可能ですかね?

これが無理なんであればデフォルトで作成されるツールバー([新規作成][開く][保存]等が入ってる)にコントロール(ボタンやリストボックス)を追加して使用、と考えているのですがこれも難しい!!!


まだまだ未熟者なのですがどうかご存知の方おられましたらご教授ください!!
よろしくお願いします!!

Aベストアンサー

Dannerです。
参考URL(英語)を載せておきます。

参考URL:http://www.codeguru.com/Cpp/controls/toolbar/placingcontrolsintoolbars/article.php/c2505/

QSEOをしています。同義語の判断はどれくらいできているのでしょうか?

当方、SEO初心者です。

Googleなどの検索エンジンは、たとえば、Visual BasicとVBを同義語として
認識しているのでしょうか?
それによっては、検索してもらうために別々のテーマでHPを作ろうと思って
います。

ご存知でしたら教えていただけないでしょうか。

Aベストアンサー

「VB」は、必ず「Visual Basic」の略であるとは限りません。
たとえば「ベンチャービジネス(Venture Business)」を略して「VB」ということもあります。
もちろん、それ以外でも何かを略して「VB」と言っているケースは色々とあると思われます。

ですから、「VB」で検索すると、
「Visual Basic」に関するページと、
「ベンチャービジネス」に関するページと、
それら以外の「VB」に関するページとが入り乱れることになります。

Googleの場合、たとえば「ダイアモンド」と「ダイヤモンド」みたいな
いわゆる「表記の揺れ」レベルであれば、
ある程度は対応しているようです。
しかし「Visual Basic」と「VB」はもちろんのこと、
たとえば「Mr.Children」と「ミスチル」などのように
名称とその略語がきちんと一対一に対応する場合であっても、
同義語として対応していないようです。

Q処理の速い当たり判定について[WINSOWS][C]

いつもお世話になっております。
WINDOWSプログラミングを勉強しています。

現在当たり判定について勉強しているのですが、調べてみたところいろいろなやり方があるようです。

私が今作ろうとしているのはアクションゲームなのですが、接地、ダメージ等々の当たり判定があり、毎フレームでこのような判定を繰り返すと重くなってしまうのでは、と危惧しています。

ここで質問なのですが、WINDOWSまたはCプログラムでなるべく速く処理ができる当たり判定を教えていただけないでしょうか?
また、初心者向けなものをお願いします。

我儘を言って申し訳ありませんが、ご指導よろしくお願いします。

Aベストアンサー

> 壁や床や敵の当たり判定は種類別にして構造体を配列にいれて判定をすればいいのですか?
> だとしたら毎フレームこれらのリージョンと自機のリージョンを判定するのでしょうか?

毎フレーム判定すれば良いと思います。
大まかな判定を先にして、それにヒットすれば細かく判定するというようにすると良いですよ。
たとえば、丸形の当たり判定は先に矩形で行ってからすると言った具合です。

> スクロールするステージを作成する予定なので、床や壁は結構多くなってしまうのですが・・・

そんなものじゃないでしょうか?
2Dのアクションゲームの場合、重くなる原因は、計算よりもむしろ描画処理だと思います。

Qhappen to meetの同義語

happen to meetの同義語

こんにちは。

run to, run into, take to, come forが選択肢としてあります。

happen to meetは偶然会う、出くわすみたいな意味なのですが、上記の中で同義語はどれでしょうか?

力を貸して頂けるとありがたいです。

Aベストアンサー

run to
http://eow.alc.co.jp/run+to/UTF-8/?ref=sa

run into
http://eow.alc.co.jp/run+into/UTF-8/

take to
http://eow.alc.co.jp/take+to/UTF-8/

come for
http://eow.alc.co.jp/come+for/UTF-8/

さあ、一体どれでしょうか?

Qfoo1.txt、foo2.txt、foo3.txt…とファイル名をつけたいとき

プログラムの一部でファイルを作成しておりまして、
foo1.txt、foo2.txt、foo3.txt…のように
foo+変数.txtとなっており、変数を変える(増やす)ことで複数のファイルを作っていきたいのですが、

このように作成したいファイル名の途中に変数を含んでいる場合、どのようにすればよいのかをご教授願います。

現在、ファイルを作成する関数(関数の中身はおそらく関係してこないと思うので割愛させていただきます)を作成し、
make("foo.txt")のように記述しておりますが詰まってしましました。
どうぞ宜しくお願いします。

Aベストアンサー

つまり
char str[16];
int count;
for(count = 0; count < 10; count++)
{
sprintf(str,"foo%d.txt",count + 1);
}
とすると
strにファイル名が入っている。

Q思惑 動作 行動 感情 形式 の同義語か対義語

この5つの言葉のうち
同義語、もしくは対義語になる言葉は
行動と形式(対義語)になるのでしょうか。
分かる方、教えて下さい。

Aベストアンサー

#1の者です。
私は
反対の意味を持つ語=対義語
同じ意味を持つ語=同義語
のつもりでお答えしたのですが、


>「形式に囚われず、行動しろ」

この文の場合、形式=きまりごと、型。という意味になりますよね。で、「形式に囚われず」とは、行動する際の条件として使われていますね。
とすると「行動」は形式の反対の意味にはなり得ません。例えば「遊ばず、勉強しろ」という文ならば、「遊ぶ」と「勉強する」が反対の意味でしょうけど、前の文ではそのような関係ではないでしょう?

よって、もし私に『「思惑 動作 行動 感情 形式」このうち同義語か反対語の関係にある二語を指摘せよ』と出題されたとしたら、「正解なし」と解答します。

試験に出題されたということですが、どのような試験かは存じませんが、あまりお気になさらなくてもいいのではないでしょうか?どのような結果になるにせよ、過ぎたことよりもその先でどう対処するか、が大切だと思いますよ(偉そうですが)。

Q[コンパイラ]xpでプログラミングの練習[フリーソフト]

大学でLINUXのemacsでプログラミングの学習をしている者です。

前からXPでそれらの練習やコンパイラに適したソフトが欲しいと思っていたのですが、
何かいいソフト、HPを紹介願えませんか?

どうかよろしくお願いします。

Aベストアンサー

 WindowsでC言語を勉強するなら、例えばコンパイラはフリーの
「Borland C++ Compiler 5.5」
を使用します。
 まず、下記からコンパイラを入手します。

http://www.borland.co.jp/cppbuilder/freecompiler/bcc55download.html

 そして、下記ページなどを参考にしてインストールします。
http://www.chem.scphys.kyoto-u.ac.jp/nonnonWWW/ogawara/lecture/borland.html

 エディッタはメモ帳でも良いですが、TeraPadというフリーソフトがお勧めです。
http://www5f.biglobe.ne.jp/~t-susumu/library/tpad.html

 TeraPadをインストール後に、
「表示」→「編集モード」→「C/C++」と
「表示」→「オプション」→「基本」→「オートインデント」
を設定すると使いやすいと思います。
 それでは、C言語の勉強頑張ってください。

参考URL:http://www5f.biglobe.ne.jp/~t-susumu/library/tpad.html

 WindowsでC言語を勉強するなら、例えばコンパイラはフリーの
「Borland C++ Compiler 5.5」
を使用します。
 まず、下記からコンパイラを入手します。

http://www.borland.co.jp/cppbuilder/freecompiler/bcc55download.html

 そして、下記ページなどを参考にしてインストールします。
http://www.chem.scphys.kyoto-u.ac.jp/nonnonWWW/ogawara/lecture/borland.html

 エディッタはメモ帳でも良いですが、TeraPadというフリーソフトがお勧めです。
http://www5f.biglobe.ne.jp/~t-susumu/libra...続きを読む


人気Q&Aランキング