[C++] もうとにかく今すぐデバッグのためのログを出力したいときの関数(C++)


もくじ

やりたいこと

C++でアプリをつくっているときに、もう何でもいいから今すぐ簡単にログを出力させて、それを見たい。
例えば、VisualStudioでデバッグ実行がしたくてもできないけど、どの経路を通ったかを知りたくて、でもMessageBoxは出したくない、かつ、Releaseビルドでやりたい(≒OutputDebugStringとかがVS上で見れない)というとき。

やり方

下記のような簡単なログ用関数を貼り付けて使用する。
終わったら、関数ごと消す。

#include <iostream>
#include <stdio.h>
#include <tchar.h>
#include <string>
#include <shlobj.h>
#include <time.h>
#include <thread>   // std::this_thread::get_id()を使うのに必要
#include <fstream>  // std::wofstreamを使うのに必要

void OutputLogToCChokka(std::wstring txt)
{
    //FILE* fp = NULL;
    auto t = time(nullptr);
    auto tmv = tm();
    auto error = localtime_s(&tmv, &t); // ローカル時間(タイムゾーンに合わせた時間)を取得

    WCHAR buf[256] = { 0 };
    wcsftime(buf, 256, L"%Y/%m/%d %H:%M:%S ", &tmv);

    // 現在のスレッドIDを出力
    auto thId = std::this_thread::get_id();

    // ログ出力
    std::wstring logtxt = buf + txt;

    // 「thread::id」型のthIdをfputやfprintf等でファイルに書くやり方がわからなかったので別の書き込み方法にした
    //auto ret = _wfopen_s(&fp, L"C:\\mylog.log", L"a+");
    //if (fp != NULL)
    //{
    //    fputws(logtxt.c_str(), fp);
    //    fclose(fp);
    //    fp = NULL;
    //}

    // ファイルを開く(なければ作成)
    // C直下のファイルに書くにはexe実行時に管理者権限にする必要アリ
    std::wofstream ofs(L"C:\\mylog.log", std::ios::app);
    if (!ofs)
    {
        return;
    }
    // 現在時刻とスレッドIDを付けたログをファイルに書き込み
    ofs << thId << L"  " << logtxt.c_str() << std::endl;
    std::wcout << thId << L"  " << logtxt.c_str() << std::endl;
    // ファイル閉じる
    ofs.close();
}

int main()
{
    OutputLogToCChokka(L"aiueo");
    system("pause");
}

※このときはいろんな都合で、その処理が走っているスレッドのIDをみたかったのでスレッドIDをログに出すようにしている。

で、C言語的書き方が好きだったのでfprintfでログに書き込みしようとしたが、「thread::id」型のthIdをfputやfprintf等でファイルに書くやり方がわからなかったので別の書き込み方法(std::wofstreamを使う方法)にした。

メモ

書いていて思いましたが、
std::wstring logtxt = buf + txt;
なんていう書き方(bufはWCHAR buf[256]、txtはstd::wstring)ができるんですね。
変な感じがします。

これのおかげなんですねきっと。