[PR]

『新妻LOVELY×CATION』を応援しています!
水無瀬の部屋 > Programming > sample > tools > snprintf.cpp
最終更新日: 2007/03/30

   1: //*********************************************************
   2: // プロジェクト: TOOLS
   3: //   ファイル名: snprintf.cpp
   4: //*********************************************************
   5: #include <header/snprintf.h> // snprintf(), vsnprintf(), 
   6: #include <header/tooldbg.h>  // ASSERT(), 
   7: #include <header/toolbase.h> // 
   8: //#include <stdio.h>           // _vsnprintf(),  
   9: 
  10: 
  11: // デバッグ時のみ
  12: #ifdef _DEBUG
  13: #include <limits.h>         // INT_MAX, 
  14: #endif // #ifdef _DEBUG
  15: 
  16: 
  17: //---------------------------------------------------------
  18: // テスト関数 の 宣言
  19: //---------------------------------------------------------
  20: DECLARE_TESTPROC( test_snprintf );
  21: 
  22: 
  23: //*********************************************************
  24: // _my_vsnprintf()
  25: //   関数 vsprintf() の出力文字数制限機能付き版。
  26: //   実際に buffer へ格納した 文字数 を返す。
  27: //   最大で bufsize-1 文字 を格納する。
  28: //   文字列終端文字 '\0' を付加する。
  29: //   ただし bufsize が 0 の場合は付加しない。
  30: //   返却値の 文字数 に文字列終端文字 '\0' は含まれない。
  31: //   格納されるはずの 文字数 が bufsize 以上の場合は 負数 を返す。
  32: // 
  33: // char *buffer
  34: //   出力先の記憶領域
  35: //
  36: // size_t bufsize
  37: //   出力先領域のサイズを 文字数 で指定する。
  38: //
  39: // const char *fmt
  40: //   出力書式文字列
  41: //   printf, sprintf, fprintf に同じ。
  42: //
  43: // va_list vp
  44: //   可変個引数
  45: //
  46: //*********************************************************
  47: int // 出力文字数
  48: _my_vsnprintf
  49: 	(
  50: 		      char    *buffer,  // 出力先の記憶領域
  51: 		      size_t   bufsize, // 出力先領域の 要素数
  52: 		const char    *fmt,     // 出力書式文字列
  53: 		      va_list  vp      // 可変個引数
  54: 	)
  55: {
  56: 	CALLONCE_TESTPROC( test_snprintf ); // [テスト]
  57: 
  58: 	// パラメタの仮定
  59: 	ASSERT( (0 <= bufsize) && (bufsize < INT_MAX) );
  60: 	ASSERT( IsValidStringBufferPtr( buffer, bufsize ) );
  61: 	ASSERT( IsValidStringPtr( fmt ) );
  62: 	DESTROY_TEXT_BUFFER( buffer, bufsize ); // [破壊]
  63: 
  64: 	// '\0' すら格納できない!
  65: 	if ( bufsize <= 0 )
  66: 	{
  67: 		return -1;
  68: 	}
  69: 
  70: 	// 書式を指定して文字列を出力する。
  71: 	ASSERT( 0 < bufsize );
  72: 	const int count = _vsnprintf( buffer, bufsize-1, fmt, vp );
  73: 	ASSERT( (count < 0)
  74: 		|| ((0 <= count) && ((size_t)count < bufsize)) );
  75: 	ASSERT( ((count < 0) || ((bufsize-1) == (size_t)count))
  76: 		|| ('\0' == buffer[ count ]) );
  77: 	
  78: 	// 文字列終端文字 '\0' を付加する。
  79: 	if ( (0 < count) && ((size_t)count < bufsize) )
  80: 	{
  81: 		buffer[ count ] = '\0';
  82: 	}	
  83: 	else
  84: 	{
  85: 		buffer[ bufsize - 1 ] = '\0';
  86: 	}
  87: 
  88: 	ASSERT( (count < 0)
  89: 		|| ((0 <= count) && (((size_t)count) < bufsize)) );
  90: 	ASSERT( ((count < 0) && ('\0' == buffer[ bufsize-1 ]))
  91: 		|| ('\0' == buffer[ count ]) );
  92: 	ASSERT( IsValidStringPtr( buffer ) );
  93: 	return (0 <= count) ? count : -1;
  94: }//_my_vsnprintf
  95: 
  96: //*********************************************************
  97: // _my_snprintf()
  98: //   関数 sprintf() の出力文字数制限機能付き版。
  99: //   実際に buffer へ格納した 文字数 を返す。
 100: //   最大で bufsize-1 文字 を格納する。
 101: //   文字列終端文字 '\0' を付加する。
 102: //   ただし bufsize が 0 の場合は付加しない。
 103: //   返却値の 文字数 に文字列終端文字 '\0' は含まれない。
 104: //   格納されるはずの 文字数 が bufsize 以上の場合は 負数 を返す。
 105: //
 106: // char *buffer
 107: //   出力先の記憶領域
 108: //
 109: // size_t bufsize
 110: //   出力先領域の 文字数
 111: //
 112: // const char *fmt
 113: //   出力書式文字列
 114: //   printf, sprintf, fprintf に同じ。
 115: //
 116: // ...
 117: //   可変個引数
 118: //
 119: //*********************************************************
 120: int // 出力文字数
 121: _my_snprintf
 122: 	(
 123: 		      char   *buffer,  // 出力先の記憶領域
 124: 		      size_t  bufsize, // 出力先領域の 文字数
 125: 		const char   *fmt,     // 出力書式文字列
 126: 		...                    // 可変個引数
 127: 	)
 128: {	
 129: 	CALLONCE_TESTPROC( test_snprintf ); // [テスト]
 130: 
 131: 	// パラメタの仮定
 132: 	ASSERT( (0 <= bufsize) && (bufsize < INT_MAX) );
 133: 	ASSERT( IsValidStringBufferPtr( buffer, bufsize ) );
 134: 	ASSERT( IsValidStringPtr( fmt ) );
 135: 	DESTROY_TEXT_BUFFER( buffer, bufsize ); // [破壊]
 136: 	
 137: 	// '\0' すら格納できない!
 138: 	if ( bufsize <= 0 )
 139: 	{
 140: 		return -1;
 141: 	}
 142: 
 143: 	// 書式を指定して文字列を出力する。
 144: 	va_list vp;
 145: 	va_start( vp, fmt );
 146: 	const int count = _my_vsnprintf( buffer, bufsize, fmt, vp );
 147: 	va_end( vp );
 148: 
 149: 	ASSERT( (-1 == count) || ((0 <= count) && ((((size_t)count) < bufsize))) );
 150: 	ASSERT( ((count < 0) && ('\0' == buffer[ bufsize-1 ]))
 151: 		|| ('\0' == buffer[ count ]) );
 152: 	ASSERT( IsValidStringPtr( buffer ) );
 153: 	return (0 <= count) ? count : -1;
 154: }//_my_snprintf
 155: 
 156: 
 157: //******************************************************************************************************************
 158: // TEST
 159: //******************************************************************************************************************
 160: 
 161: 
 162: #ifdef _DEBUG // デバッグ時のみ
 163: 
 164: 
 165: //*********************************************************
 166: // test_snprintf
 167: //*********************************************************
 168: DEFINE_TESTPROC( test_snprintf )
 169: {
 170: 	//---------------------------------------------------------
 171: 	// 定数 の テスト
 172: 	//---------------------------------------------------------
 173: 
 174: 	//---------------------------------------------------------
 175: 	// ファイルスコープ関数 の テスト
 176: 	//---------------------------------------------------------
 177: 
 178: 	//---------------------------------------------------------
 179: 	// 公開関数 の テスト
 180: 	//---------------------------------------------------------
 181: 
 182: 	const struct
 183: 		{
 184: 			      int     count;
 185: 			const char   *string;
 186: 			      size_t  bufsize;
 187: 			const char   *result;
 188: 		}
 189: 	testcase[] =
 190: 		{
 191: #define MAKE_TESTCASE( count, string, bufsize, result ) { count, string, bufsize, result }
 192: 			MAKE_TESTCASE(  -1, "",   0, ""   ),
 193: 			MAKE_TESTCASE(   0, "",   1, ""   ),
 194: 			MAKE_TESTCASE(   0, "",   2, ""   ),
 195: 			MAKE_TESTCASE(  -1, "-",  0, ""   ),
 196: 			MAKE_TESTCASE(  -1, "-",  1, ""   ),
 197: 			MAKE_TESTCASE(   1, "-",  2, "-"  ),
 198: 			MAKE_TESTCASE(   1, "-",  3, "-"  ),
 199: 			MAKE_TESTCASE(  -1, "--", 0, ""   ),
 200: 			MAKE_TESTCASE(  -1, "--", 1, ""   ),
 201: 			MAKE_TESTCASE(  -1, "--", 2, "-"  ),
 202: 			MAKE_TESTCASE(   2, "--", 3, "--" ),
 203: 			MAKE_TESTCASE(   2, "--", 4, "--" ),
 204: #undef MAKE_TESTCASE
 205: 		};
 206: 	{for( int i = 0; i < numof( testcase ); ++i )
 207: 	{
 208: 		char buffer[ 1024 ];
 209: 		const int count = _my_snprintf( buffer, testcase[ i ].bufsize, "%s", testcase[ i ].string );
 210: 		VERIFY( count == testcase[ i ].count );
 211: 		VERIFY( (0 == testcase[ i ].bufsize)
 212: 		     || streql( buffer, testcase[ i ].result ) );
 213: 	}}
 214: 
 215: }//test_snprintf
 216: 
 217: 
 218: #endif // #ifdef _DEBUG
 219: 
 220: 
 221: //** end **
 222: 

参照:


Google
ご意見・ご感想をお聞かせ下さい。匿名で送信できます。

 * 返信が必要な場合には postmaster@katsura-kotonoha.sakura.ne.jp へ直接メールしてください。

水無瀬の部屋 > sample > tools > snprintf.cpp

このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/snprintf_cpp.shtml
『新妻LOVELY×CATION』を応援しています!