C++ 使用模板(template) 扩展std::string


Github: https://github.com/hpsocket/cpp_utils/blob/master/string_helper.hpp

string_helper.hpp

/*
* Author: hpsocket (https://github.com/hpsocket)
* License: Code Project Open License
* Disclaimer: The software is provided "as-is". No claim of suitability, guarantee, or any warranty whatsoever is provided.
* Copyright (c) 2016-2017.
*/

#ifndef _STRING_HELPER_HPP_INCLUDED_
#define _STRING_HELPER_HPP_INCLUDED_

#include <stdarg.h>
#include <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <iomanip>

namespace string_helper
{
	inline std::string format(const char *fmt, ...)
	{
		std::string strResult = "";
		if (NULL != fmt)
		{
			va_list marker = NULL;
			va_start(marker, fmt);

			size_t nLength = _vscprintf(fmt, marker) + 1;
			std::vector<char> vBuffer(nLength, '\0');

			int nRet = _vsnprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
			if (nRet > 0)
			{
				strResult = &vBuffer[0];

			}

			va_end(marker);
		}
		return strResult;
	}

	inline std::wstring format(const wchar_t *fmt, ...)
	{
		std::wstring strResult = L"";
		if (NULL != fmt)
		{
			va_list marker = NULL;
			va_start(marker, fmt);

			size_t nLength = _vscwprintf(fmt, marker) + 1;
			std::vector<wchar_t> vBuffer(nLength, L'\0');

			int nWritten = _vsnwprintf_s(&vBuffer[0], vBuffer.size(), nLength, fmt, marker);
			if (nWritten > 0)
			{
				strResult = &vBuffer[0];
			}

			va_end(marker);
		}
		return strResult;
	}

	template <class T>
	inline std::vector<std::basic_string<T>> compact(const std::vector<std::basic_string<T>> &tokens)
	{
		std::vector<std::basic_string<T>> compacted;
		for (size_t i = 0; i < tokens.size(); ++i) {
			if (!tokens[i].empty()) {
				compacted.push_back(tokens[i]);
			}
		}
		return compacted;
	}

	template <class T>
	inline std::vector<std::basic_string<T>> split(const std::basic_string<T>& str, const std::basic_string<T>& delim, const bool trim_empty = false)
	{
		size_t pos, last_pos = 0, len;
		std::vector<std::basic_string<T>> tokens;
		while (true) {
			pos = str.find(delim, last_pos);
			if (pos == std::wstring::npos) {
				pos = str.size();
			}
			len = pos - last_pos;
			if (!trim_empty || len != 0) {
				tokens.push_back(str.substr(last_pos, len));
			}
			if (pos == str.size()) {
				break;
			}
			else {
				last_pos = pos + delim.size();
			}
		}
		return tokens;
	}

	template <class T>
	inline std::basic_string<T> join(const std::vector<std::basic_string<T>> &tokens,const std::basic_string<T>& delim, const bool trim_empty = false)
	{
		if (trim_empty) {
			return join(compact(tokens), delim, false);
		}
		else {
			std::basic_stringstream<T> ss;
			for (size_t i = 0; i < tokens.size() - 1; ++i) {
				ss << tokens[i] << delim;
			}
			ss << tokens[tokens.size() - 1];
			return ss.str();
		}
	}

	template <class T>
	inline std::basic_string<T> trim(const std::basic_string<T>& str)
	{
		if (str.empty()) {
			return str;
		}
		std::basic_string<T> sstr(str);
		std::basic_string<T>::iterator c;
		// Erase whitespace before the string  
		for (c = sstr.begin(); c != sstr.end() && iswspace(*c++);); sstr.erase(sstr.begin(), --c);
		// Erase whitespace after the string  
		for (c = sstr.end(); c != sstr.begin() && iswspace(*--c);); sstr.erase(++c, sstr.end());
		return sstr;
	}

	template <class T>
	inline std::basic_string<T> repeat(const std::basic_string<T>& str, unsigned int times)
	{
		std::basic_stringstream<T> ss;
		for (unsigned int i = 0; i < times; ++i) {
			ss << str;
		}
		return ss.str();
	}

	template <class T>
	inline std::basic_string<T> Toupper(const std::basic_string<T>& str)
	{
		if (str.empty()) {
			return str;
		}
		std::basic_string<T> s(str);
		std::transform(s.begin(), s.end(), s.begin(), toupper);
		return s;
	}

	template <class T>
	inline std::basic_string<T> Tolower(const std::basic_string<T>& str)
	{
		if (str.empty()) {
			return str;
		}
		std::basic_string<T> s(str);
		std::transform(s.begin(), s.end(), s.begin(), tolower);
		return s;
	}

	template <class T>
	inline std::basic_string<T> replace(const std::basic_string<T>& source,const std::basic_string<T>& target,const std::basic_string<T>& replacement)
	{
		std::basic_string<T> s(source);
		std::basic_string<T>::size_type pos = 0;
		std::basic_string<T>::size_type srclen = target.size();
		std::basic_string<T>::size_type dstlen = replacement.size();
		while ((pos = s.find(target, pos)) != std::basic_string<T>::npos)
		{
			s.replace(pos, srclen, replacement);
			pos += dstlen;
		}
		return s;
	}

	template <class T>
	inline std::basic_string<T> between(const std::basic_string<T>& str, const std::basic_string<T>& left, const std::basic_string<T>& right) {
		size_t left_pos, right_pos, last_pos = 0;
		left_pos = str.find(left, last_pos);
		if (left_pos == std::basic_string<T>::npos)
			return std::basic_string<T>();
		last_pos = left_pos + left.size();
		right_pos = str.find(right, last_pos);
		if (right_pos == std::basic_string<T>::npos)
			return std::basic_string<T>();
		return str.substr(left_pos + left.size(), right_pos - left_pos - left.size());
	}

	template <class T>
	inline std::vector<std::basic_string<T>> between_array(const std::basic_string<T>& str, const std::basic_string<T>& left, const std::basic_string<T>&right, const bool trim_empty = false)
	{
		size_t left_pos, right_pos, last_pos = 0, len;
		std::vector<std::basic_string<T>> result;
		while (true) {
			left_pos = str.find(left, last_pos);
			if (left_pos == std::basic_string<T>::npos) {
				break;
			}
			else
			{
				last_pos = left_pos + left.size();
				right_pos = str.find(right, last_pos);
				if (right_pos == std::basic_string<T>::npos) {
					break;
				}
				len = right_pos - left_pos - left.size();
				if (len != 0 || !trim_empty)
				{
					result.push_back(str.substr(last_pos, len));
				}
			}
			last_pos = right_pos + right.size();
		}
		return result;
	}

	template <class T>
	inline std::basic_string<T> left(const std::basic_string<T>& str, const std::basic_string<T>& left)
	{
		std::basic_string<T> s(str);
		size_t pos, last_pos = 0;
		pos = s.find(left, last_pos);
		if (pos != std::basic_string<T>::npos)
			return s.substr(0, pos);
		else
			return std::basic_string<T>();
	}

	template <class T>
	inline std::basic_string<T> right(const std::basic_string<T>& str, const std::basic_string<T>& right)
	{
		std::basic_string<T> s(str);
		size_t pos, last_pos = 0;
		pos = s.find(right, last_pos);
		if (pos != std::basic_string<T>::npos)
		{
			pos += right.length();
			return s.substr(pos, str.length() - pos);
		}
		else
			return std::basic_string<T>();
	}

	template <class T>
	inline bool is_start_with(const std::basic_string<T>& str, const std::basic_string<T>& src)
	{
		return str.compare(0, src.length(), src) == 0;
	}

	template <class T>
	inline bool is_end_with(const std::basic_string<T>& str, const std::basic_string<T>& src)
	{
		return str.compare(str.length() - src.length(), src.length(), src) == 0;
	}
}

#endif // _STRING_HELPER_HPP_INCLUDED_

###test.cpp

#include "stdafx.h"
#include <iostream>
#include "textconv_helper.hpp"

int main()
{
	std::wstring s = L" Hello World!! ";
	std::wcout << s << L" size:" << s.size() << std::endl;
	std::wcout << string_helper::trim(s) << L" size:" << string_helper::trim(s).size() << std::endl;
	std::wcout << string_helper::Toupper(s) << s.size() << std::endl;
	std::wcout << string_helper::Tolower(s) << s.size() << std::endl;

	std::wcout << string_helper::repeat<wchar_t>(s, 5) << s.size() << std::endl;

	std::vector<std::wstring> v;
	v.push_back(L"1");
	v.push_back(L"");
	v.push_back(L"2");
	v.push_back(L"3");
	v.push_back(L"");
	// v: ["1", "", "2", "3", ""]
	v = string_helper::compact(v);
	// v: ["1", "2", "3"]

	for each (auto item in v)
	{
		std::wcout << item << std::endl;
	}

	std::wstring xxxx = L";";

	std::wstring x = string_helper::join(v, xxxx);
	std::wcout << x << std::endl;

	v = string_helper::split(std::wstring(L"one,two,three"), std::wstring(L",")); // v: ["one", "two", "three"]
	for each (auto item in v)
	{
		std::wcout << item << std::endl;
	}

	std::wstring r = string_helper::replace(std::wstring(L"1-2-3-4"), std::wstring(L"-"), std::wstring(L"#")); // v: "1#2#3#4"

	std::wcout << r << std::endl;

	r = string_helper::between(s, std::wstring(L"X"), std::wstring(L"d"));// s: "ello Worl"

	std::wcout << r << std::endl;

	getchar();

    return 0;
}
Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐