⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdstring.h

📁 这是一个非常好的、可以替代mfc中的CString的字符串类。支持ansi、unicode。
💻 H
📖 第 1 页 / 共 5 页
字号:
	}

	CStdStr(MYSIZE nSize, MYVAL ch, const MYALLOC& al=MYALLOC())
		: MYBASE(nSize, ch, al)
	{
	}

	#ifdef SS_INC_COMDEF
		CStdStr(const _bstr_t& bstr)
		{
			if ( bstr.length() > 0 )
				this->append(static_cast<PCMYSTR>(bstr), bstr.length());
		}
	#endif

	// CStdStr inline assignment operators -- the ssasn function now takes care
	// of fixing  the MSVC assignment bug (see knowledge base article Q172398).
	MYTYPE& operator=(const MYTYPE& str)
	{ 
		ssasn(*this, str); 
		return *this;
	}

	MYTYPE& operator=(const std::string& str)
	{
		ssasn(*this, str);
		return *this;
	}

	MYTYPE& operator=(const std::wstring& str)
	{
		ssasn(*this, str);
		return *this;
	}

	MYTYPE& operator=(PCSTR pA)
	{
		ssasn(*this, pA);
		return *this;
	}

	MYTYPE& operator=(PCWSTR pW)
	{
		ssasn(*this, pW);
		return *this;
	}

#ifdef SS_ALLOW_UNSIGNED_CHARS
	MYTYPE& operator=(PCUSTR pU)
	{
		ssasn(*this, static_cast<PCSTR>(pU)):
		return *this;
	}
#endif

	MYTYPE& operator=(CT t)
	{
		Q172398(*this);
		this->assign(1, t);
		return *this;
	}

	#ifdef SS_INC_COMDEF
		MYTYPE& operator=(const _bstr_t& bstr)
		{
			if ( bstr.length() > 0 )
			{
				this->assign(static_cast<PCMYSTR>(bstr), bstr.length());
				return *this;
			}
			else
			{
				this->erase();
				return *this;
			}
		}
	#endif


	// Overloads  also needed to fix the MSVC assignment bug (KB: Q172398)
	//  *** Thanks to Pete The Plumber for catching this one ***
	// They also are compiled if you have explicitly turned off refcounting
	#if ( defined(_MSC_VER) && ( _MSC_VER < 1200 ) ) || defined(SS_NO_REFCOUNT) 

		MYTYPE& assign(const MYTYPE& str)
		{
			ssasn(*this, str);
			return *this;
		}

		MYTYPE& assign(const MYTYPE& str, MYSIZE nStart, MYSIZE nChars)
		{
			// This overload of basic_string::assign is supposed to assign up to
			// <nChars> or the NULL terminator, whichever comes first.  Since we
			// are about to call a less forgiving overload (in which <nChars>
			// must be a valid length), we must adjust the length here to a safe
			// value.  Thanks to Ullrich Poll鋒ne for catching this bug

			nChars		= SSMIN(nChars, str.length() - nStart);

			// Watch out for assignment to self

			if ( this == &str )
			{
				MYTYPE strTemp(str.c_str()+nStart, nChars);
				MYBASE::assign(strTemp);
			}
			else
			{
				Q172398(*this);
				MYBASE::assign(str.c_str()+nStart, nChars);
			}
			return *this;
		}

		MYTYPE& assign(const MYBASE& str)
		{
			ssasn(*this, str);
			return *this;
		}

		MYTYPE& assign(const MYBASE& str, MYSIZE nStart, MYSIZE nChars)
		{
			// This overload of basic_string::assign is supposed to assign up to
			// <nChars> or the NULL terminator, whichever comes first.  Since we
			// are about to call a less forgiving overload (in which <nChars>
			// must be a valid length), we must adjust the length here to a safe
			// value. Thanks to Ullrich Poll鋒ne for catching this bug

			nChars		= SSMIN(nChars, str.length() - nStart);

			// Watch out for assignment to self

			if ( this == &str )	// watch out for assignment to self
			{
				MYTYPE strTemp(str.c_str() + nStart, nChars);
				MYBASE::assign(strTemp);
			}
			else
			{
				Q172398(*this);
				MYBASE::assign(str.c_str()+nStart, nChars);
			}
			return *this;
		}

		MYTYPE& assign(const CT* pC, MYSIZE nChars)
		{
			// Q172398 only fix -- erase before assigning, but not if we're
			// assigning from our own buffer

	#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 )
			if ( !this->empty() &&
				( pC < this->data() || pC > this->data() + this->capacity() ) )
			{
				this->erase();
			}
	#endif
			Q172398(*this);
			MYBASE::assign(pC, nChars);
			return *this;
		}

		MYTYPE& assign(MYSIZE nChars, MYVAL val)
		{
			Q172398(*this);
			MYBASE::assign(nChars, val);
			return *this;
		}

		MYTYPE& assign(const CT* pT)
		{
			return this->assign(pT, MYBASE::traits_type::length(pT));
		}

		MYTYPE& assign(MYCITER iterFirst, MYCITER iterLast)
		{
	#if defined ( _MSC_VER ) && ( _MSC_VER < 1200 ) 
			// Q172398 fix.  don't call erase() if we're assigning from ourself
			if ( iterFirst < this->begin() || iterFirst > this->begin() + this->size() )
				this->erase()
	#endif
				this->replace(this->begin(), this->end(), iterFirst, iterLast);
			return *this;
		}
	#endif


	// -------------------------------------------------------------------------
	// CStdStr inline concatenation.
	// -------------------------------------------------------------------------
	MYTYPE& operator+=(const MYTYPE& str)
	{
		ssadd(*this, str);
		return *this;
	}

	MYTYPE& operator+=(const std::string& str)
	{
		ssadd(*this, str);
		return *this; 
	}

	MYTYPE& operator+=(const std::wstring& str)
	{
		ssadd(*this, str);
		return *this;
	}

	MYTYPE& operator+=(PCSTR pA)
	{
		ssadd(*this, pA);
		return *this;
	}

	MYTYPE& operator+=(PCWSTR pW)
	{
		ssadd(*this, pW);
		return *this;
	}

	MYTYPE& operator+=(CT t)
	{
		this->append(1, t);
		return *this;
	}
	#ifdef SS_INC_COMDEF	// if we have _bstr_t, define a += for it too.
		MYTYPE& operator+=(const _bstr_t& bstr)
		{
			return this->operator+=(static_cast<PCMYSTR>(bstr));
		}
	#endif


	// addition operators -- global friend functions.

	friend	MYTYPE	operator+(const MYTYPE& str1,	const MYTYPE& str2);
	friend	MYTYPE	operator+(const MYTYPE& str,	CT t);
	friend	MYTYPE	operator+(const MYTYPE& str,	PCSTR sz);
	friend	MYTYPE	operator+(const MYTYPE& str,	PCWSTR sz);
	friend	MYTYPE	operator+(PCSTR pA,				const MYTYPE& str);
	friend	MYTYPE	operator+(PCWSTR pW,			const MYTYPE& str);
#ifdef SS_INC_COMDEF
	friend	MYTYPE	operator+(const _bstr_t& bstr,	const MYTYPE& str);
	friend	MYTYPE	operator+(const MYTYPE& str,	const _bstr_t& bstr);
#endif

	// -------------------------------------------------------------------------
	// Case changing functions
	// -------------------------------------------------------------------------
	// -------------------------------------------------------------------------
	MYTYPE& ToUpper()
	{
		//  Strictly speaking, this would be about the most portable way

		//	std::transform(begin(),
		//				   end(),
		//				   begin(),
		//				   std::bind2nd(SSToUpper<CT>(), std::locale()));

		// But practically speaking, this works faster

		if ( !empty() )
			ssupr(GetBuf(), this->size());

		return *this;
	}



	MYTYPE& ToLower()
	{
		//  Strictly speaking, this would be about the most portable way

		//	std::transform(begin(),
		//				   end(),
		//				   begin(),
		//				   std::bind2nd(SSToLower<CT>(), std::locale()));

		// But practically speaking, this works faster

		if ( !empty() )
			sslwr(GetBuf(), this->size());

		return *this;
	}



	MYTYPE& Normalize()
	{
		return Trim().ToLower();
	}


	// -------------------------------------------------------------------------
	// CStdStr -- Direct access to character buffer.  In the MS' implementation,
	// the at() function that we use here also calls _Freeze() providing us some
	// protection from multithreading problems associated with ref-counting.
	// -------------------------------------------------------------------------
	CT* GetBuf(int nMinLen=-1)
	{
		if ( static_cast<int>(size()) < nMinLen )
			this->resize(static_cast<MYSIZE>(nMinLen));

		return this->empty() ? const_cast<CT*>(this->data()) : &(this->at(0));
	}

	CT* SetBuf(int nLen)
	{
		nLen = ( nLen > 0 ? nLen : 0 );
		if ( this->capacity() < 1 && nLen == 0 )
			this->resize(1);

		this->resize(static_cast<MYSIZE>(nLen));
		return const_cast<CT*>(this->data());
	}
	void RelBuf(int nNewLen=-1)
	{
		this->resize(static_cast<MYSIZE>(nNewLen > -1 ? nNewLen : sslen(this->c_str())));
	}

	void BufferRel()		 { RelBuf(); }			// backwards compatability
	CT*  Buffer()			 { return GetBuf(); }	// backwards compatability
	CT*  BufferSet(int nLen) { return SetBuf(nLen);}// backwards compatability

	bool Equals(const CT* pT, bool bUseCase=false) const
	{	// get copy, THEN compare (thread safe)
		return  bUseCase ? this->compare(pT) == 0 : ssicmp(MYTYPE(*this).c_str(), pT) == 0;
	} 

	// -------------------------------------------------------------------------
	// FUNCTION:  CStdStr::Load
	// REMARKS:
	//		Loads string from resource specified by nID
	//
	// PARAMETERS:
	//		nID - resource Identifier.  Purely a Win32 thing in this case
	//
	// RETURN VALUE:
	//		true if successful, false otherwise
	// -------------------------------------------------------------------------
#ifndef SS_ANSI
	bool Load(UINT nId, HMODULE hModule=NULL)
	{
		bool bLoaded		= false;	// set to true of we succeed.

	#ifdef _MFC_VER		// When in Rome...

		CString strRes;
		bLoaded				= FALSE != strRes.LoadString(nId);
		if ( bLoaded )
			*this			= strRes;

	#else
		
		// Get the resource name and module handle

		if ( NULL == hModule )
			hModule			= GetResourceHandle();

		PCTSTR szName		= MAKEINTRESOURCE((nId>>4)+1); // lifted 
		DWORD dwSize		= 0;

		// No sense continuing if we can't find the resource

		HRSRC hrsrc			= ::FindResource(hModule, szName, RT_STRING);

		if ( NULL == hrsrc )
		{
			TRACE(_T("Cannot find resource %d: 0x%X"), nId, ::GetLastError());
		}
		else if ( 0 == (dwSize = ::SizeofResource(hModule, hrsrc) / sizeof(CT)))
		{
			TRACE(_T("Cant get size of resource %d 0x%X\n"),nId,GetLastError());
		}
		else
		{
			bLoaded			= 0 != ssload(hModule, nId, GetBuf(dwSize), dwSize);
			ReleaseBuffer();
		}

	#endif

		if ( !bLoaded )
			TRACE(_T("String not loaded 0x%X\n"), ::GetLastError());

		return bLoaded;
	}
#endif
	
	// -------------------------------------------------------------------------
	// FUNCTION:  CStdStr::Format
	//		void _cdecl Formst(CStdStringA& PCSTR szFormat, ...)
	//		void _cdecl Format(PCSTR szFormat);
	//           
	// DESCRIPTION:
	//		This function does sprintf/wsprintf style formatting on CStdStringA
	//		objects.  It looks a lot like MFC's CString::Format.  Some people
	//		might even call this identical.  Fortunately, these people are now
	//		dead.
	//
	// PARAMETERS: 
	//		nId - ID of string resource holding the format string
	//		szFormat - a PCSTR holding the format specifiers
	//		argList - a va_list holding the arguments for the format specifiers.
	//
	// RETURN VALUE:  None.
	// -------------------------------------------------------------------------
	// formatting (using wsprintf style formatting)
	#ifndef SS_ANSI
	void Format(UINT nId, ...)
	{
		va_list argList;
		va_start(argList, nId);
		va_start(argList, nId);

		MYT

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -