[C/C++]zltabout(インデント付きフォーマット出力)v 1.0.同じコードでC FILEまたはC++ストリームにバインドできます
8715 ワード
作者:zyl 910
一、缘由
テキストを生成するプログラムを書くときには、インデント付きフォーマット出力の機能が必要になることがよくあります.以前はこのために似たような関数をたくさん書いたことがありますが、残念ながら再利用性が悪いです.これは,1)C言語のFILE*が自分のバッファへのリダイレクトをサポートしていないためである.2)C++のフローメカニズムにより、自分のフローバッファにリダイレクトすることができる.残念ながらこれはC++の専有文法に依存しており、純Cでは使えません.
以上の理由から、以前は少なくともCとC++の2つの関数セットを記述しなければならなかった.char/wchat_を考えるとt/TCHARは,関数集会がより肥大化している.
そこで、「C FILEまたはC++ストリームに同じコードでバインドできる」というインデント付きフォーマット出力ライブラリを作成することにしました.zltaboutはこの考えの成果である.
二、C例
Step 1 ZLTABOUTMODEマクロとzltaboutの導入を定義する.h:
#define ZLTABOUTMODE 1 //ZLTABOUTMODE_C #include "zltabout.h"
Step 2 ZLTOUTYPEタイプの変数を定義してstdoutとする:
ZLTOUTTYPE sout; sout = (ZLTOUTTYPE)stdout;
Step 3 zltoutcを使用して文字を出力します.
zltoutc(sout, _T(''));
Step 4 zltouts出力文字列を使用する:
static const TCHAR strEnd[] = _T("(END)"); zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
Step 5 zltoutfを使用してインデント付きフォーマット出力を行う:
for(i=0; i<3;++i) { zltoutf(sout, i, _T("indent %d"), i); }
完全なコード:
出力結果:
三、C++例
Step 1 ZLTABOUTMODEマクロとzltaboutの導入を定義する.h:
#define ZLTABOUTMODE 2 //ZLTABOUTMODE_CPP #include "zltabout.h"
Step 2 ZLTOUTYPEタイプの変数を定義し、cout/wcoutとして割り当てます.
ZLTOUTTYPE sout; #ifdef UNICODE sout = dynamic_cast(&wcout); #else sout = dynamic_cast(&cout); #endif
Step 3 zltoutcを使用して文字を出力します.
zltoutc(sout, _T(''));
Step 4 zltouts出力文字列を使用する:
static const TCHAR strEnd[] = _T("(END)"); zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
Step 5 zltoutfを使用してインデント付きフォーマット出力を行う:
for(i=0; i<3;++i) { zltoutf(sout, i, _T("indent %d"), i); }
完全なコード:
注意:ZLTOUTYPEをstringstreamにバインドすることもできます.たとえば、
四、クイックリファレンス
一般的な関数:
構成マクロを入力:
* ZL_NOWIDE:ワイド文字版関数は定義しない.bcb 6.*などの互換性の向上に使用ZLTABOUTMODE:出力モード.値は、0(ZLTABOUTMODE_DUMMY)、1(ZLTABOUTMODE_C)、2(ZLTABOUTMODE_CPP)とすることができる.
ソースのダウンロードhttps://github.com/zyl910/zltabout
一、缘由
テキストを生成するプログラムを書くときには、インデント付きフォーマット出力の機能が必要になることがよくあります.以前はこのために似たような関数をたくさん書いたことがありますが、残念ながら再利用性が悪いです.これは,1)C言語のFILE*が自分のバッファへのリダイレクトをサポートしていないためである.2)C++のフローメカニズムにより、自分のフローバッファにリダイレクトすることができる.残念ながらこれはC++の専有文法に依存しており、純Cでは使えません.
以上の理由から、以前は少なくともCとC++の2つの関数セットを記述しなければならなかった.char/wchat_を考えるとt/TCHARは,関数集会がより肥大化している.
そこで、「C FILEまたはC++ストリームに同じコードでバインドできる」というインデント付きフォーマット出力ライブラリを作成することにしました.zltaboutはこの考えの成果である.
二、C例
Step 1 ZLTABOUTMODEマクロとzltaboutの導入を定義する.h:
#define ZLTABOUTMODE 1 //ZLTABOUTMODE_C #include "zltabout.h"
Step 2 ZLTOUTYPEタイプの変数を定義してstdoutとする:
ZLTOUTTYPE sout; sout = (ZLTOUTTYPE)stdout;
Step 3 zltoutcを使用して文字を出力します.
zltoutc(sout, _T(''));
Step 4 zltouts出力文字列を使用する:
static const TCHAR strEnd[] = _T("(END)"); zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
Step 5 zltoutfを使用してインデント付きフォーマット出力を行う:
for(i=0; i<3;++i) { zltoutf(sout, i, _T("indent %d"), i); }
完全なコード:
#include <stdio.h>
#include <wchar.h>
#include "auto_tchar.h"
#include "auto_tmain.h"
#define ZLTABOUTMODE 1 // ZLTABOUTMODE_C
#include "zltabout.h"
/// main .
int _tmain(int argc, TCHAR* argv[])
{
ZLTOUTTYPE sout;
static const TCHAR strEnd[] = _T("(END)");
int i;
// show.
sout = (ZLTOUTTYPE)stdout;
for(i=0; i<3; ++i) {
zltoutf(sout, i, _T("indent %d
"), i);
}
zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
zltoutc(sout, _T('
'));
return 0;
}
出力結果:
indent 0
indent 1
indent 2
(END)
三、C++例
Step 1 ZLTABOUTMODEマクロとzltaboutの導入を定義する.h:
#define ZLTABOUTMODE 2 //ZLTABOUTMODE_CPP #include "zltabout.h"
Step 2 ZLTOUTYPEタイプの変数を定義し、cout/wcoutとして割り当てます.
ZLTOUTTYPE sout; #ifdef UNICODE sout = dynamic_cast
Step 3 zltoutcを使用して文字を出力します.
zltoutc(sout, _T(''));
Step 4 zltouts出力文字列を使用する:
static const TCHAR strEnd[] = _T("(END)"); zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
Step 5 zltoutfを使用してインデント付きフォーマット出力を行う:
for(i=0; i<3;++i) { zltoutf(sout, i, _T("indent %d"), i); }
完全なコード:
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <wchar.h>
#include "auto_tchar.h"
#include "auto_tmain.h"
//#define ZLTABOUTMODE 1 // ZLTABOUTMODE_C
#define ZLTABOUTMODE 2 // ZLTABOUTMODE_CPP
#include "zltabout.h"
using namespace std;
/** test mode ( ).
*
* values:
* * 1: Test cout/wcout .
* * 2: Test stringstream/wstringstream .
*
*/
#define MYTESTMODE 2
/// Do Test.
void dotest(ZLTOUTTYPE sout, int indent) {
static const TCHAR strEnd[] = _T("(END)");
int i;
for(i=0; i<3; ++i) {
zltoutf(sout, indent+i, _T("indent %d
"), i);
}
zltouts(sout, strEnd, sizeof(strEnd)/sizeof(strEnd[0])-1);
zltoutc(sout, _T('
'));
}
/// main .
int _tmain(int argc, TCHAR* argv[])
{
ZLTOUTTYPE sout;
// show.
#if ZLTABOUTMODE==ZLTABOUTMODE_DUMMY
sout = (ZLTOUTTYPE)NULL;
#elif ZLTABOUTMODE==ZLTABOUTMODE_C
sout = (ZLTOUTTYPE)stdout;
#elif ZLTABOUTMODE==ZLTABOUTMODE_CPP
#if (MYTESTMODE==1)
// test cout/wcout .
#ifdef UNICODE
sout = dynamic_cast<ZLTOUTTYPEW>(&wcout);
#else
sout = dynamic_cast<ZLTOUTTYPEA>(&cout);
#endif
#elif (MYTESTMODE==2)
// test stringstream/wstringstream .
basic_stringstream<TCHAR> ss;
sout = dynamic_cast<ZLTOUTTYPE>(&ss);
#endif
#else
#error Error ZLTABOUTMODE !
#endif
dotest(sout, 0);
#if (ZLTABOUTMODE==ZLTABOUTMODE_CPP) && (MYTESTMODE==2)
// test stringstream/wstringstream part 2.
basic_string<TCHAR> str = ss.str();
#ifdef UNICODE
wcout << str;
#else
cout << str;
#endif
#endif
return 0;
}
注意:ZLTOUTYPEをstringstreamにバインドすることもできます.たとえば、
ZLTOUTTYPE sout;
basic_stringstream<TCHAR> ss;
sout = dynamic_cast<ZLTOUTTYPE>(&ss);
dotest(sout, 0);
basic_string<TCHAR> str = ss.str();
#ifdef UNICODE
wcout << str;
#else
cout << str;
#endif
四、クイックリファレンス
一般的な関数:
// Output stream's type ( ).
#define ZLTOUTTYPE // C FILE* or C++ basic_ostream .
// Writes a character to a stream ( ).
int zltoutc(ZLTOUTTYPE sout, TCHAR ch);
// Write a string to a stream ( ).
void zltouts(ZLTOUTTYPE sout, const TCHAR* str, size_t cch);
// Formatted output with indentation using a pointer to a list of arguments ( ).
void zltoutvf(ZLTOUTTYPE sout, int indent, const TCHAR* fmt, va_list argptr);
//Formatted output with indentation ( ).
void zltoutf(ZLTOUTTYPE sout, int indent, const TCHAR* fmt, ...);
構成マクロを入力:
* ZL_NOWIDE:ワイド文字版関数は定義しない.bcb 6.*などの互換性の向上に使用ZLTABOUTMODE:出力モード.値は、0(ZLTABOUTMODE_DUMMY)、1(ZLTABOUTMODE_C)、2(ZLTABOUTMODE_CPP)とすることができる.
ソースのダウンロードhttps://github.com/zyl910/zltabout