ソースには一切手を加えず、(5)ファイルのクローズでエラー表示させる方法はないでしょうか。

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
FILE *fp;/* (1)ファイルポインタの宣言 */
char s[256];

/* (2)ファイルのオープン */
/* ここで、ファイルポインタを取得する */
if ((fp = fopen("smpl.txt", "r")) == NULL) {
printf("file open error!!\n");
exit(EXIT_FAILURE);/* (3)エラーの場合は通常、異常終了する */
}

/* (4)ファイルの読み(書き)*/
while (fgets(s, 256, fp) != NULL) {

/* ここではfgets()により1行単位で読み出し */
printf("%s", s);
}
if((fclose(fp)) == EOF){/* (5)ファイルのクローズ */
Logging(cfancname, 2);
printf("ファイルクローズに失敗しました\n");
return -1;
}

return 0;
}

宜しくお願いします。

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

A 回答 (6件)

本題とは関係ないのですが、


> exit(EXIT_FAILURE); /* (3)エラーの場合は通常、異常終了する */
> return -1;
> return 0;
統一が取れていないのと、-1を返すのはあまりよろしくないかと。
上から順に、
return EXIT_FAILURE;
return EXIT_FAILURE;
return EXIT_SUCCESS;
とするか、
return 1;
return 1;
return 0;
がいいかと。
    • good
    • 0

たぶん、fclose()がエラーのケースで、


Loggingやprintfが正しく動作するか
走行確認したいのだと思いますが、
おそらくfclose()のエラーは、入力パラメータ(ファイルポインタ)が
不正なケースでしか発生しないと思います。
http://www.linux.or.jp/JM/html/LDP_man-pages/man …

私だったら、
if((fclose(fp)) == EOF){ /* (5)ファイルのクローズ */
の実行直前に、デバッガでfpの値をNULLに変更して続行させます。
    • good
    • 0

本物じゃないfopen~fcloseを作りリンクしてテストするしかないでしょう。


http://yougo.ascii.jp/caltar/%E3%82%B9%E3%82%BF% …
こういう場合に使うモジュールをスタブと呼びます。
    • good
    • 0

要は、動作確認をしたいが、動作確認後、ソースを変えたくない


というのが、質問の趣旨であれば、
int ret;の変数を確保し
if((fclose(fp)) == EOF){ /* (5)ファイルのクローズ */

ret = fclose(fp); (1)
if (ret == EOF){  (2)
の2行に分けます。
デバッガで(1)を実行した後、(2)で止めます。
その後、ret にEOFの値をセットします。
その後、実行を再会します。
もちろん、デバッグ完了後も、
ソースは(1)と(2)に分けたままにしておきます。
    • good
    • 0

環境依存かつとてもシビアなタイミングになりうるけど「ファイルが存在するデバイスそのものを切り離す」とかやるとできるかもしれない.


「(5)ファイルのクローズでエラー表示させる」の意味が今一つ分かりませんが. 純粋に「fclose の中でエラー表示させる」という意味だとむしろ「どれだけプログラムをいじっても無駄」だし.
    • good
    • 0

ソースに手を加えない、という条件下では、むずかしいのではないでしょうか。


もっとも、私が知らないだけかもしれませんけれど…。
    • good
    • 0

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

FC 意味」に関するQ&A: Close to Youの意味

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

Qfcloseで発生するエラーについて。

昨日「windowsプログラムのデバッグ」で投稿させて頂いた者です。

要点は「どのようなときにfcloseがエラーをおこすか」です。

Windowsプログラムでバグを探したところデバッグ用のログ出力ファイルを
fcloseする時にエラーがおこりプログラムがエラーを起こして終了している
ことがわかりました。

プログラムを実行させて一定操作を行うと、プログラムの最後に行われるfcloseでエラーが起こります。
プログラムを実行させてそのまま(×等で)終了させたときにはエラーが起こらずに正常な書き込みがされているので、
メッセージの処理等をしている間に変な処理を入れてしまているのだと思いますが、
実際にログファイルへの書き込みはfcloseの直前までできているのでなぜエラーが起こるのかよくわかりません。

if((fp=fopen("log.txt","w")==NULL)return -1;
とやっているのでfopenは成功していると思います。

fcloseがエラーとなるのはどのような原因が考えられるのでしょうか。

「意味がわからないので~を説明しろ」等でも構いませんのでご回答お願いいたします。

【環境】
VC6.0++ProffessionalEdition
windows2000
【その他】
-エラー文の内容-
"0x77fcc465"の命令が"0xfffdfffa"のメモリを参照しました。
メモリが"read"になることはできませんでした。

昨日「windowsプログラムのデバッグ」で投稿させて頂いた者です。

要点は「どのようなときにfcloseがエラーをおこすか」です。

Windowsプログラムでバグを探したところデバッグ用のログ出力ファイルを
fcloseする時にエラーがおこりプログラムがエラーを起こして終了している
ことがわかりました。

プログラムを実行させて一定操作を行うと、プログラムの最後に行われるfcloseでエラーが起こります。
プログラムを実行させてそのまま(×等で)終了させたときにはエラーが起こらずに正常な書き込みがされ...続きを読む

Aベストアンサー

こんにちわ。

一つ確認させて下さい。
fclose の直後に、別の処理を追加してみて下さい。
→ 別のファイルにログを採取するようなものだけで結構です。
これで、log.txtのfclose が正常に動作するようであれば、
スタックを壊してしまっているために、異常なリターンアドレスに
復帰しようとした可能性が高いです。
→ 獲得したローカル変数に領域を越えてデータを読み込んで
  しまった時等に、このようなエラーが発生する事があります。
  (fclose の問題ではなく、呼び出し元の関数に復帰する時に
  エラーとなった事が考えられます。)

スタック破壊の場合、問題の関数内の処理の一部をコメントアウトして、
エラーが発生するかどうかを調べると、比較的容易に問題の箇所を
特定できると思います。

Qfopne で失敗する原因

fopenで失敗する原因とはなんですか?

Aベストアンサー

#1の方の回答に加えて...

・ファイル名の文字列がでたらめ(存在するかどうか以前の問題)
・指定したファイル名が実はディレクトリだった。
・ファイル名に空ポインタまたは不正なポインタを渡した。
・オープンモードに空ポインタまたは不正なポインタを渡した。
・オープンモードの形式が不正
・メモリ不足でバッファ(実装によってはファイル記述子も)の割り付けに失敗した。
・同名の関数またはマクロをユーザーが定義した。
・関数原型なしで呼び出した。
・他のスレッド等で、同じファイルに対する操作中(再入可能とは限らないので)

Qfloat型とdouble型の変数の違いを教えてほしいです

float型とdouble型の変数の違いを教えてほしいです
2Dゲームを作っててdoubleの変数を使ってたんですが使ってはだめだと先輩に言われたんです。
理由を聞いたら、先生が「doubleは使わないほうがいい」と言われたらしくてちゃんとした理由がわかりませんでした。
それを知って何をするということではないんですが、気になって調べても出てこなかったので質問させてください。
まだゲーム作りを始めたばっかりでぜんぜん詳しくないですが教えてくれたら助かります。

Aベストアンサー

doubleとfloatでは、精度が違い、そのためメモリに占める大きさも違います。
また、一般的には、桁が多いとその分計算時間がかかります。
ですから、精度が必要ない場面では、floatを使う、というのも一つの考えかたです。

ですが、実際には「一概に言えない、処理系依存」です。

以前は全てCPUで計算していたので、精度=計算量でした。
しかし、最近では浮動小数点演算専用の回路が付いているケースが多く、計算時間は同じだったり、doubleに変換が必要でその分floatの方が遅かったり、floatでの演算はより高速にできたり、と様々です。
32bitCPUでは、32bitのfloatの方が扱いやすいでしょうが、64bitCPUでは64bitのdoubleの方が扱いやすいかもしれません。
Cのmath.hで使える標準関数はdouble型のものがほとんどです。三角関数は2Dのゲームでも使う機会が多いのではないでしょうか。sinもcosもdouble型です。内部演算は当然doubleですので、変数にfloatを使ったからと早くはならず、むしろfloat型の変数に入れるときに暗黙の型変換が発生する分遅くなる可能性もあります。

そういった背景を考え検討した結果、floatを使う方がよい、と判断したのならいいのですが、「先生に言われた」では理由になりません。
聞けるのなら、その先生に理由を聞いてください。真意がわからないうちは、鵜呑みしないことです。

doubleとfloatでは、精度が違い、そのためメモリに占める大きさも違います。
また、一般的には、桁が多いとその分計算時間がかかります。
ですから、精度が必要ない場面では、floatを使う、というのも一つの考えかたです。

ですが、実際には「一概に言えない、処理系依存」です。

以前は全てCPUで計算していたので、精度=計算量でした。
しかし、最近では浮動小数点演算専用の回路が付いているケースが多く、計算時間は同じだったり、doubleに変換が必要でその分floatの方が遅かったり、floatでの演算はより高速...続きを読む

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む

Qchar*を初期化したいのですが

Cの標準関数だけで
char*を初期化したいのですが
どの様にすればいいのでしょうか?

char* a = "aaaa";
char* b = "bbbb";
strcat( a, b );//"aaaabbbb"?
とし使いまた後で
aにまた値を入れ直したいので
初期化して再利用したいのですが

どのようにすればいいのでしょうか?

ポインタとかもうっすら(ほとんどわかりません)
よろしくお願いいたします

Aベストアンサー

> char* a = "aaaa";
> char* b = "bbbb";
> strcat( a, b );//"aaaabbbb"?
この上のコードは間違っていますよ。
変数a、bに入っているのはあくまでも文字列の"ポインタ"です。
従いまして、strcat( a, b );とすると、aがさしているメモリは5バイトしかないのでメモリを破壊してしまいます。
static char sza[] = "aaaa";
static char szb[] = "bbbb";
char szBuffer[256];
char* a = szBuffer;
strcpy (a, sza);
strcat (a, szb);
としないとだめです。

またポインタ変数はNULLで初期化可能です。

Q複数桁10進数の*桁目だけを抽出したい

タイトルがすべてと言えてしまうのですが、
例えば、int宣言された"4287"(この値は変動します)という数値があったとして、1桁目の"7"だけを別の変数へ引き抜きたいのですが、その場合にはANDによるマスク処理による演算で処理可能なのでしょうか?
また、他に良い方法などありましたら教えていただけますでしょうか?

Aベストアンサー

★10進数ですので AND は使えませんね。
・簡単なサンプルを載せますので読み取って下さい。

サンプル1:
int value = 4287;
int a[ 4 ];

a[0] = (value % 10); value /= 10; // 1桁目を取り出す
a[1] = (value % 10); value /= 10; // 2桁目を取り出す
a[2] = (value % 10); value /= 10; // 3桁目を取り出す
a[3] = (value % 10); value /= 10; // 4桁目を取り出す

サンプル2:
int value = 4287;
int a;

a = (value % 10);
value -= a;

value → 4280
a → 7
になります。

Qsleep()関数について

"数秒おきに警報をn回鳴らすプログラム"をC言語で作成しようと
考えています。

プログラム実行環境はWindowsですが、
sleep()関数は使用できないのでしょうか??

仮に使用できない場合、この関数に代わる関数や代替方法が
あれば教えて頂けませんでしょうか? 宜しくお願いします。

Aベストアンサー

正確な動作でも構わなければ
windows.hをインクルードして
Sleep()関数を使いましょう.
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200207/02070061.txt

しかし,正確に数秒おきに動作を行いたい場合はマルチメディアタイマ等を使いましょう.
マルチメディアタイマはミリ秒間隔でコールバック関数を呼び出すことができます.
timeSetEventを用いてコールバック関数の登録を行うことができます.
timeKillEventでコールバック関数の解除を行うことができます.

多分他にも方法があると思うのですが…私はこれぐらいしか知りません^^;

参考URL:http://www.katto.comm.waseda.ac.jp/~katto/Class/GazoTokuron/code/time.html

QC言語のfopenについて教えてください。

C言語のfopenについて教えてください。

ある1つのファイルをr(テキストファイル読み込みモード)でfopenしたとします。
そのファイルをfcloseする前に、同じファイルが再度rモードでfopenされても問題ないのでしょうか?

何を気にしているかと言いますと、あるプログラムであるファイルをrモードでfopenして読み込む処理があるのですが、そのプログラムを呼び出す処理が複数あります。
確率は低いと言えど、もし同時にその処理が実行された場合、rモードでfopenしているファイルにfclose前に再度rモードのfopenがされたらエラーとなってしまうのでしょうか?
もし、エラーとなる場合、回避する方法がありますか?
また、エラーとならない場合は、fcloseするまで次の処理が待ってしまうのでしょうか?

読み込みモードだから問題ないのかなとも思ったのですが、どなたかご存知だったら教えてください。

よろしくお願いしますm(_ _)m

Aベストアンサー

同じプロセス内の話ならオープンしたファイルハンドルごとで
ファイルハンドルは管理しているので
開きっぱなしでもオープンできる限りはエラーになりません。
ただし、同時にオープンできるファイル数には限界があるので
無尽蔵に開き続けるような場合にはいずれオープンに失敗します
(そういうerrnoがあったはず)
オープンできる限界については
プロセスごとと、OS(カーネルパラメータ)の2段階だった予感

なので、1つのプログラムならば
オープンしたファイルのパス名とハンドルを別管理する等
同じファイルの複数オープンは修正しておいた方がいいと思うけれど
複数のプログラム(実行モジュール)でアクセスしていて
変更できないのなら仕方ないですね。

ただ、
読み取り中に変更されてしまう可能性と変更されると都合悪い場合には
考え直した方がよいですね。
起動元でファイル名にシーケンス番号をつけて渡してあげるとかして
そのファイル名をユニークしてあげるとか

QC言語---ファイルに出力したデータをすべて消去する方法

C言語の話です。

はじめ、ファイルを"w"モードで開き、
fprintfで繰り返してデータをファイルに書き込んで、
ある条件(何らかのエラーがおきた場合)には今まで書き込んだものは
すべて 消去します。
(つまり、ファイルを再び空にするという意味です。)
この場合、もうこれ以上ファイルに書き込むことはしないで、プログラムは終了します。

書き込んだものを消去するには、どのようにすればよいですか。

「一度ファイルを閉じて、再び"w"モードで開き、また閉じる」
というのが私が考えるいちばん簡単な方法なんですが、
ファイルの中身を消去するために開いたり閉じたりしなきゃいけないの?
という気もします。

本で見ると、freopenという関数が使えそうな気もしますが、
わたしはこの関数を使ったことがありませんし、
解説を読んでも、本当にこのような場合に使うものなのかな、
という感じがします。

そんなにプログラミングに詳しくないので、やさしくご回答いただけるとたすかります。

Aベストアンサー

その時点で開いているファイル(書き込み中のファイル)
のFile Descripterを閉じた後、
---
fclose(oldfp);
FILE *fp = fopen(filename, "w");
fclose(fp);
---
とするか、
---
freopen(filename, "w", oldfp);
---
の何れかを実行すれば、ファイルサイズ0
(中身が空)のファイルが作成されます。

やはり一旦閉じた後、モード "w" で
再度開きなおすのがセオリーでしょう。

Qセグメンテーション違反

C言語を使用しています。

構造体に値をいれようとしたら、コンパイルは出来るのですが、実行時に
「セグメンテーション違反です (core dumped)」
となってしまい、それ以上行えません。

構造体と代入したい変数との型は、合っています。

いろいろ本などで見ましたが、何が原因かわからず困っています。
教えてください。
宜しくお願いします。

Aベストアンサー

OSは何でしょうか。コンパイラは何を使用していますか?
通常、デバッグオプションをつけて実行すると、異常の発生したソースの箇所で止まりますので、それが手がかりになります。またNo1の方が言われてますように、ソースが公開できるのであれば、ソースを提示するのが良いかと思います。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報