ウインドウズアプリを作ると、テキストファイルをよく扱います。

その時、必要になるのがトリミングです。
トリミングとは前後の空白文字やタブ文字を消すことです。

MFCのCStringだとTrim関数が提供されてますが、WinAPIではありません。

よく使うので作りました。

STLを使って文字列をトリミングする

STLのstringとwstringを使ってます。

■ std::string の場合

/**
 * @brief  トリミング
 * @param  String トリミングする文字列
 * @return なし
 **/
void Trim( std::string &String )
{
	// 後ろから空白文字を探して消していく
	auto itr = String.begin();
	while( itr != String.end() )
	{
		// タブ文字 or 半角スペース or 全角スペース
		if( ( *itr == '\t' ) || ( *itr == ' ' ) || ( *itr == ' ' ) )
		{
			itr = String.erase( itr );
		}
		else
		{
			break;
		}
	}

	// 後ろから空白文字を探して消していく
	auto ritr = String.rbegin();
	while( ritr != String.rend() )
	{
		// タブ文字 or 半角スペース or 全角スペース
		if( ( *ritr == '\t' ) || ( *ritr == ' ' ) || ( *itr == ' ' ) )
		{
			ritr ++;
			auto itr = ritr.base();
			String.erase( itr );
		}
		else
		{
			break;
		}
	}
}

■ std::wstring の場合

/**
 * @brief  トリミング
 * @param  String トリミングする文字列
 * @return なし
 **/
void Trim( std::wstring &String )
{
	// 前から空白文字を探して消していく
	auto itr = String.begin();
	while( itr != String.end() )
	{
		// タブ文字 or 半角スペース or 全角スペース
		if( ( *itr == '\t' ) || ( *itr == ' ' ) || ( *itr == ' ' ) )
		{
			itr = String.erase( itr );
		}
		else
		{
			break;
		}
	}

	// 後ろから空白文字を探して消していく
	auto ritr = String.rbegin();
	while( ritr != String.rend() )
	{
		// タブ文字 or 半角スペース or 全角スペース
		if( ( *ritr == '\t' ) || ( *ritr == ' ' ) || ( *itr == ' ' ) )
		{
			ritr ++;
			auto itr = ritr.base();
			String.erase( itr );
		}
		else
		{
			break;
		}
	}
}

引数に渡した文字列がそのまま編集されるので注意してください

STLを使わないで文字列をトリミングする

STLは使いたくないという時もあるでしょう。
文字列のポインタ操作だけでやるなら以下のようにすればできます。

■ char の場合

/**
 * @brief  トリミング
 * @param  pText 対象文字列
 * @param  msBuf トリミングした文字列を入れるバッファ
 * @return なし
 **/
void Trim( char *pText, char *msBuf )
{
	char *p = pText;
	char *pTop = NULL, *pEnd = NULL;

	// 改行 or 文字列終端で終了
	while( ( *p != '\0' ) && ( *p != '\r' ) && ( *p != '\n' ) )
	{
		// 改行、半角スペース、全角スペースでないなら先頭を保存
		if( ( *p != '\t' ) && ( *p != ' ' ) && ( *p != ' ' ) )
		{
			// 先頭を保存
			if( !pTop )
			{
				pTop = p;
			}

			// 文字列終端ではなかったので再度検索
			pEnd = NULL;
		}
		else
		{
			if( !pEnd )
			{
				pEnd = p;
			}
		}

		p ++;
	}

	if( !pEnd )
	{
		pEnd = p;
	}

	if( pTop && pEnd )
	{
		int nLength = pEnd - pTop;
		memcpy( msBuf, pTop, nLength );
		msBuf[ nLength ] = '\0';
	}
	else
	{
		msBuf[ 0 ] = '\0';
	}
}

■ wchar_t(TCHAR) の場合

/**
 * @brief  トリミング
 * @param  pText 対象文字列
 * @param  wsBuf トリミングした文字列を入れるバッファ
 * @return なし
 **/
void Trim( TCHAR *pText, TCHAR *wsBuf )
{
	TCHAR *p = pText;
	TCHAR *pTop = NULL, *pEnd = NULL;

	// 改行 or 文字列終端で終了
	while( ( *p != L'\0' ) && ( *p != L'\r' ) && ( *p != L'\n' ) )
	{
		// 改行、半角スペース、全角スペースでないなら先頭を保存
		if( ( *p != L'\t' ) && ( *p != L' ' ) && ( *p != L' ' ) )
		{
			// 先頭を保存
			if( !pTop )
			{
				pTop = p;
			}

			// 文字列終端ではなかったので再度検索
			pEnd = NULL;
		}
		else
		{
			if( !pEnd )
			{
				pEnd = p;
			}
		}

		p ++;
	}

	if( !pEnd )
	{
		pEnd = p;
	}

	if( pTop && pEnd )
	{
		int nLength = ( pEnd - pTop );
		memcpy( wsBuf, pTop, nLength << 1 );
		wsBuf[ nLength ] = L'\0';
	}
	else
	{
		wsBuf[ 0 ] = L'\0';
	}
}

STLを使わない場合は、トリミングされた文字が第二引数で指定されたバッファに保存されます。
充分な長さのメモリを確保しておいてください

スポンサーリンク