ページ 11

ログファイルについて

Posted: 2010年7月02日(金) 00:41
by ちょん
初めまして。ちょんと申します。
現在ログ出力関数を作成しているのですが、一つ難点がありまして皆さんにお聞きしたいと思います。

環境はXP, bcc5.5になります。
int WriteLog(const char *format, ...)
{
    FILE         *fp;
    va_list     list;
    char        formatStr[32];

    if ((fp = fopen("Log.txt", "a")) == NULL) {
        return -1;
    }
    
      va_start(list, format);
      
    SetDateTimeFormat(formatStr);
    fprintf(fp, formatStr);
      vfprintf(fp, format, list);
      
      va_end(list);
      fclose(fp);

      return 0;
}
exeを実行するとプログラムに沿ってログを出力するのですが、一度実行が終わりログが溜まった後、
もう一度実行すると、そのまま続けて次の実行したプログラムのログが出力されてしまうので大変見づらいので
改行を出力したいのですが、なかなかいいアイディアが思いつきません。。。
グローバル変数で回数を記憶することも考えたのですが、どうもごり押しな気がします。。。
何か良い方法はないでしょうか?

<例>分かりにくくてすみません。
最初のログ
最初のログ
最初のログ
次のログ
次のログ
次のログ
今現在は上記のようになってしまいます。それを
最初のログ
最初のログ
最初のログ

次のログ
次のログ
次のログ
こんな感じにしたいです。

皆さまよろしくお願いいたします。

Re:ログファイルについて

Posted: 2010年7月02日(金) 00:51
by Justy
 もう一度実行する際にログファイルが既にあったら(既に書き込まれていたら)改行を出力、でいいのでは?

Re:ログファイルについて

Posted: 2010年7月02日(金) 00:58
by めるぽん
int WriteLog(const char *format, ...)
{
    static bool written = false;
    ...
    if (!wrriten)
    {
        // ここら辺に改行とかを書き込む
        wrriten = true;
    }
    ...
}
とすれば、アプリケーション実行のたびに最初の WriteLog 呼び出しだけ特有の操作ができそうです。

Re:ログファイルについて

Posted: 2010年7月02日(金) 01:23
by フリオ
 
 プログラムを終了するときに、改行のみの行をログとして出力する
と言うのは、だめでしょうか。
 

Re:ログファイルについて

Posted: 2010年7月02日(金) 01:52
by ちょん
皆さんありがとうございます。
>Justyさん
>既に書き込まれていたら
今回、ログ出力の度にクローズしているので、既に書きこまれていたらという条件ですと、
いつの書き込みが最後の書き込みか把握できず、出来ないような気がします。。。
私の考え違いでしたらすみません。

>ぬるぽんさん
サンプルありがとうございます。
上手く動作したのですが、何故か余計な部分で改行が入ってしまいます。
実は自分がグローバルでフラグを立ててやっていた時もそのような状況になりまして、
今だ原因がわからないままです。

>フリオさん
申し遅れてすみません。、このプログラムは終了のタイミングが決まっていないため、
その方法ですと出来ないです。提示を忘れましてすみません。

やはり他の部分のバグなのでしょうか。。。
プログラムをアップしてみたいと思いますのでよろしければ見ていただけないでしょうか?

Re:ログファイルについて

Posted: 2010年7月02日(金) 02:05
by ちょん
http://www1.axfc.net/uploader/Sc/so/129629.zip&key=tyon
アップしてみました。
キーワードはtyonになります。

使い方としましてはInteg.batを叩くとコンパイルされますので、
binフォルダにあるexeを起動して下さい。

コマンドとしましてはsever.exe client.exeを起動した後にclientで7を入力して接続した後、
どのコマンドでもいいので計算を行って下さい。
その状態でログを見ると何故かserver.c [143] SRV:select() Startの次の行が改行になってしまっています。
これは何故なんでしょうか?

よろしくお願いいたします。 画像

Re:ログファイルについて

Posted: 2010年7月02日(金) 02:46
by めるぽん
>server.c [143] SRV:select() Start の次の行が改行になってしまっています。
改行されないのが問題じゃなかったんですか?
> 上手く動作したのですが、何故か余計な部分で改行が入ってしまいます。
という部分は入っていないみたいですし。


コンパイルと実行はしていないので予想ですけど、もしかして
>server.c [143] SRV:select() Start
の後ろに表示されるのは client.c のログだったりしませんか?
そうだとすれば、server と client は別のアプリケーションだから
グローバル変数が共有されないために起こっているんじゃないかなと思います。


その場合はserverとclientで別のファイルにログを出すか、
serverやclientの起動と終了のログを確実に書き出すようにすればよさそうです。

Re:ログファイルについて

Posted: 2010年7月02日(金) 03:04
by めるぽん
あ、client.c じゃなくて(client.c から呼び出された)socketLib.cのログですかね。

Re:ログファイルについて

Posted: 2010年7月02日(金) 03:17
by ちょん
>server.c [143] SRV:select() Start の次の行が改行になってしまっています。
改行されないのが問題じゃなかったんですか?
> 上手く動作したのですが、何故か余計な部分で改行が入ってしまいます。
という部分は入っていないみたいですし。

すみません。ぬるぽんさんのコード反映させたものと違うものをアップしてしまいました。。。orz

clientにはログ出力の部分はないはずなんですが。。。う~ん。。。
ちなみに今回はログを別ファイルに分けるのではなく統一して出したいと思っています。

今日は寝ます。
遅くまで付き合っていただきありがとうございました。

Re:ログファイルについて

Posted: 2010年7月02日(金) 03:23
by ちょん
あっ!
socketLib.cのほうでしたか。
ちょっとまだわからないですね。

ちなみにグローバル変数を使っていたときはexternで宣言してログファイルに定義して
いまして、その時はグローバル変数の値が保持されているのを確認しました。

にもかかわらず、ログのserver.c [143] SRV:select() Start
この部分の次の行が改行されてしまっていまして、何処に問題があるか検討がつかない状態です。

また明日に聞きに来たいと思います。
ありがとうございました。

Re:ログファイルについて

Posted: 2010年7月02日(金) 03:48
by めるぽん
・サーバ側で使用しているグローバル変数
・クライアント側で使用しているグローバル変数
というのは別の扱いになります。
グローバル変数で共有されるのは、同じアプリケーションの異なる翻訳単位(.cpp)間のみです。
アプリケーション間で共有されたりはしません。

>グローバル変数の値が保持されている
というのは、サーバ側で使用しているグローバル変数を調べただけではないのでしょうか。
クライアント側で使用しているグローバル変数は書き換わっていない可能性が高そうです。

順番を追っていくとこんな感じですかね。
1.サーバ側でログファイルを出力する
  →サーバ側のグローバル変数 written が false なので、改行を出力して written を true にする
2.クライアント側で ConnectServer 等を呼び出し、その中でログファイルを出力する
  →クライアント側のグローバル変数 written が false なので、改行を出力して written を true にする


で、統一して書き出したい場合、そもそもサーバとクライアントの生存期間は同じではないでしょうから、
単に改行を出力するだけだと、それがサーバの起動なのかクライアントの起動なのか分からないと思うのですけれども・・・。

>最初のログ
>最初のログ
>最初のログ
> // ここはサーバの起動?サーバの終了?クライアントの起動?クライアントの終了?
>次のログ
>次のログ
>次のログ

なのでクライアントやサーバの起動と終了をちゃんと書いてやるのがいいのかなと思います。
main関数があるのですから、フリオさんのおっしゃるように
> プログラムを終了するときに、改行のみの行をログとして出力する
というのを起動時や終了時に行うのはできるのではないでしょうか。

Re:ログファイルについて

Posted: 2010年7月02日(金) 07:42
by toyo
必ずサーバ側から起動すれば
// winSockの初期化
WriteLog("%s [%d] SRV:WSAStartup() Start\n", FILE, LINE);

// winSockの初期化
WriteLog("\n%s [%d] SRV:WSAStartup() Start\n", FILE, LINE);
にするだけですみそうですが

Re:ログファイルについて

Posted: 2010年7月02日(金) 09:25
by ちょん
おはようございます。

>ぬるぽんさん
>グローバル変数の値が保持されている
>というのは、サーバ側で使用しているグローバル変数を調べただけではないのでしょうか。
>クライアント側で使用しているグローバル変数は書き換わっていない可能性が高そうです。
その通りでした。すみません勘違いしていました。
おっしゃる通りです。

>で、統一して書き出したい場合、そもそもサーバとクライアントの生存期間は同じではないでしょうから、
>単に改行を出力するだけだと、それがサーバの起動なのかクライアントの起動なのか分からないと思うのですけれども・・・。
そうですよね。。。

>プログラムを終了するときに、改行のみの行をログとして出力する
>というのを起動時や終了時に行うのはできるのではないでしょうか。
フリオさんのこの考えでやってみます!

>toyoさん
それですと。ログは日付と時間も表していて、それをWriteLog関数の中でやっているので、
2010 07/02 Fri 09:15:17
server.c [36] SRV:WSAStartup() Start
このようにファイル名より後ろだけ改行される形になってしまいます。

Re:ログファイルについて

Posted: 2010年7月02日(金) 10:09
by ちょん
アホな質問で申し訳ありません。
サーバー側のmainにfpを宣言したのですが、
何故かfpが未定義と怒られます。。。orz
int main(void)
{
    int     sockValue;
    FILE    *fp;

    if (InitSockServer(&sockValue)) {
        return -1;
    }
    
    GetRequestClient(sockValue);
    
    WriteLog(fp, "\n");

    return 0;
}
これって何が悪いのでしょうか?

Re:ログファイルについて

Posted: 2010年7月02日(金) 10:27
by ちょん
WriteLog関数の引数は違いますが、fpの宣言で怒られるのは違うような気が。。。
あと、この方法だと、サーバーをctr + cで終了したときに終了位置がわからないと思います。
この場合どうすればよいのでしょうか?

Re:ログファイルについて

Posted: 2010年7月02日(金) 10:50
by へろりくしょん
>これって何が悪いのでしょうか?

stdio.h あたりがインクルードされてないからじゃないですか?

その翻訳単位からFILE 構造体の定義が見えてないからじゃないかと。

Re:ログファイルについて

Posted: 2010年7月02日(金) 10:57
by ちょん
stdio.hはmain関数のあるファイル上部にインクルードしているのに駄目なのです。。。orz

Re:ログファイルについて

Posted: 2010年7月02日(金) 12:11
by ちょん
fpが未定義と出るのはもしかしたらmakeが悪いのでしょうか。。。

普通に別ファイルでの宣言なら上手くいきますが、server.c client.cで
mainにfpを宣言すると未定義のエラーが出てしまいます。

Re:ログファイルについて

Posted: 2010年7月02日(金) 12:31
by toyo
改行の仕様を確認したいのですが
サーバ起動
クライアント起動
クライアント終了
クライアント起動
サーバ終了
クライアント終了
この場合改行はどこに入れたいですか
最後だけ改行であれば他のプロセスが起動中か確認する必要があるのでちょっと面倒ですよね
プロセス起動時にファイル作成、終了時に削除とかして別のプロセスからはファイルの有無を確認するとか

Re:ログファイルについて

Posted: 2010年7月02日(金) 12:53
by ちょん
やはり最後だけいれたいですね。

>最後だけ改行であれば他のプロセスが起動中か確認する必要があるのでちょっと面倒ですよね
>プロセス起動時にファイル作成、終了時に削除とかして別のプロセスからはファイルの有無を確認するとか
そうなってくるとちょっと面倒ですよね。
でも最後だけ入れたいのでやりたいですね!
ただファイルポインタがシンボルエラーになる問題が解決しておらずまだ進めない状況です^^;