C++自定义的工具函数
my_function.h

1 #pragma once 2 #include <iostream> 3 #include <cstdarg> 4 #include <list> 5 #include <limits> 6 #include <vector> 7 #include <codecvt> 8 #include <cstdlib> 9 #include <comdef.h> 10 #include <string> 11 12 #ifndef MY_FUNCTION_H_ 13 #undef max //取消max的宏定义,他是由comdef.h带进来的,会干扰正常编译 14 #define MY_FUNCTION_H_ 15 namespace MY_TOOLS { 16 /* 17 * 专用于输入double类型的变量;处理用户输入,确保用户输入的是合法数字;对于数字和字符混合的输入,数字在前的读取数字,后续的字符丢弃;若是字符在前,则要求重新输入 18 * 返回int值EXIT_SUCCESS 19 * result_int:用于存放用户输入的整型数字,double*指针,对应的存放空间必须在调用之前分配好; 20 * hint_str:const char*指针,用于提示输入的字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 21 * error_message:在用户输入错误的情况下,提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 22 */ 23 int in_double(double& result_int, const char* hint_str, const char* error_message = {}); 24 /* 25 * 处理用户输入,只处理char字符数组; 26 * result_str:char*指针,用于存放用户输入的字符,对应的存放空间必须在调用之前分配好; 27 * len:无符号整型,用于指定result_str最多能存储多少个字符(不包括NULL),也就是说,若是result_str能存放10个字符,那么len最多只能传递9;len的最大允许范围为0~(UINT_MAX-1) 28 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 29 * error_message:const char*指针,在用户输入错误的情况下(长度过长,或者输入为空),提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 30 * 输入成功会返回EXIT_SUCCESS 31 * 在len的值等于UINT_MAX时会返回EXIT_FAILURE 32 */ 33 int in_charArray(char* result_str, unsigned int len, const char* hint_str, const char* error_message = {}); 34 /* 35 * 处理用户输入,专用于输入单个字符;对于输入了多个字符的输入,只取第一个字符,后续字符全部丢弃 36 * result_str:char*指针,用于存放用户输入的字符,对应的存放空间必须在调用之前分配好; 37 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 38 * error_message:const char*指针,在用户输入错误的情况下(长度过长,或者输入为空),提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 39 * 输入成功会返回EXIT_SUCCESS 40 * 在len的值等于UINT_MAX时会返回EXIT_FAILURE 41 */ 42 int in_char(char& result_char, const char* hint_str, const char* error_message = {}); 43 /* 44 * 处理用户输入,专用于输入单个宽字符;对于输入了多个字符的输入,只取第一个字符,后续字符全部丢弃 45 * result_str:char*指针,用于存放用户输入的字符,对应的存放空间必须在调用之前分配好; 46 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 47 * error_message:const char*指针,在用户输入错误的情况下(长度过长,或者输入为空),提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 48 * 输入成功会返回EXIT_SUCCESS 49 * 在len的值等于UINT_MAX时会返回EXIT_FAILURE 50 */ 51 int in_wchar_t(wchar_t& result_char, const wchar_t* hint_str, const wchar_t* error_message = {}); 52 /* 53 * in_uint:处理用户输入,确保用户输入的是正整数; 54 * result_int:用于存放用户输入的整型数字,unsigned int*指针,对应的存放空间必须在调用之前分配好; 55 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 56 * error_message:const char*指针,在用户输入错误的情况下,提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 57 */ 58 int in_uint(unsigned int& result_int, const char* hint_str, const char* error_message = {}); 59 /* 60 * in_int:处理用户输入,确保用户输入的是整数; 61 * result_int:用于存放用户输入的整型数字,int*指针,对应的存放空间必须在调用之前分配好; 62 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 63 * error_message:const char*指针,在用户输入错误的情况下,提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 64 */ 65 int in_int(int& result_int, const char* hint_str, const char* error_message = {}); 66 /* 67 * in_long:处理用户输入,确保用户输入的是整数; 68 * result_int:用于存放用户输入的整型数字,int*指针,对应的存放空间必须在调用之前分配好; 69 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 70 * error_message:const char*指针,在用户输入错误的情况下,提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 71 */ 72 long in_long(long& result_int, const char* hint_str, const char* error_message = {}); 73 /* 74 * 函数功能:简单实现类似于python 中的format功能;该函数将会重载,以适应不同的情况; 75 * 注意,你需要保证,args不定数量参数中的每个参数都要为const char*类型; 76 * 注意:你需要保证,str中的{}数量与args中参数的数量对应,否则会触发未定义行为。 77 * 使用示例:std::cout << MY_IN::format("我的名字:{}。{}", "aaa","今天阳光明媚!\n"); 78 */ 79 std::string format(const std::string str, ...); 80 /* 81 * 注意:宽字符版本format实现很有难度,这里没有实现,建议使用对应的swprintf 82 * 函数功能:简单实现类似于python 中的format功能;该函数将会重载,以适应不同的情况; 83 * 注意,你需要保证,args不定数量参数中的每个参数都要为const wchar_t*类型; 84 * 注意:你需要保证,str中的{}数量与args中参数的数量对应,否则会触发未定义行为。 85 * 使用示例:std::wcout << MY_IN::format(L"我的名字:{}。{}", L"aaa",L"今天阳光明媚!\n"); 86 */ 87 std::wstring format(const wchar_t* str, ...); 88 89 /* 90 * in_uint_scope:处理用户输入,确保用户输入的是正整数,且输入的值处于指定范围内; 91 * result_int: 用于存放用户输入的整型数字,unsigned int*指针,对应的存放空间必须在调用之前分配好; 92 * start_num: 范围的起始值,若是start_num大于等于end_num,函数将抛出异常( L"起始值大于等于截止值!") 93 * end_num: 范围的结束值,范围将包含该结束值; 94 * hint_str:const char*指针,提示字符串的地址,用于提示用户的输入,字符串建议在结尾处添加换行符; 95 * error_message:const char*指针,在用户输入错误的情况下,提示用户的信息字符串的地址,可以为空,为空则不提示,字符串建议在结尾处添加换行符 96 */ 97 int in_uint_scope(unsigned int& result_int, unsigned int start_num, unsigned int end_num, const char* hint_str, const char* error_message = {}); 98 /* 99 * 变大写,将给定的wstring、string、char数组、wchar_t数组里面的字母变为大写字母 100 * 直接修改原来的变量 101 * 目前只支持char和wchar_t类型的字符 102 * value:需要变大写的变量,引用方式 103 * start_index:从哪里开始修改 104 * numberOfChar:修改多少个字符 105 */ 106 template<typename T> 107 void toUppercase(T& value, unsigned start_index, unsigned numberOfChar) { 108 //判断是哪种字符 109 if (sizeof(value[0]) == sizeof(char)) { 110 for (unsigned i = start_index; i < numberOfChar; i++) { 111 value[i] = toupper(value[i]); 112 } 113 } 114 else if (sizeof(value[0]) == sizeof(wchar_t)) { 115 for (unsigned i = start_index; i < numberOfChar; i++) { 116 value[i] = towupper(value[i]); 117 } 118 } 119 else { 120 ; 121 } 122 } 123 124 /*string字符串分割函数:split 125 * 返回list对象 126 * value:表示被分割的字符串 127 * character:分隔符 128 * len:字符串长度 129 */ 130 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::list<std::string>split(const std::string value, char character, size_t len); 131 132 /*wstring字符串分割函数:split 133 * 返回list对象 134 * value:表示被分割的字符串 135 * character:分隔符 136 * len:字符串长度 137 */ 138 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::list<std::wstring>split(const std::wstring value, wchar_t character, size_t len); 139 /*wstring字符串分割函数:split_vector:返回类型为vector 140 * 返回vector对象 141 * value:表示被分割的字符串 142 * character:分隔符 143 * len:字符串长度 144 */ 145 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::vector<std::wstring>split_vector(std::wstring& value, wchar_t character, size_t len); 146 /*wstring字符串分割函数:split_vector:返回类型为vector 147 * 返回vector对象 148 * value:表示被分割的字符串,传递wchar_t*类型 149 * character:分隔符 150 * len:字符串长度 151 */ 152 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::vector<std::wstring>split_vector(const wchar_t* value, wchar_t character, size_t len); 153 /*返回list对象的第几个值 154 * 若是下标越界,将返回一个默认初始化的T对象,同时将is_success置为false 155 * List:list对象 156 * index:下标,从0开始 157 * is_success:执行是否成功;输出参数 158 */ 159 template<typename T> 160 const T list_at(std::list<T> List, unsigned index, bool* is_success = nullptr) { 161 if (index >= List.size()) { 162 if (is_success) { 163 *is_success = false; 164 } 165 return T{}; 166 } 167 else { 168 T ret{}; 169 unsigned i{}; 170 for (auto& v : List) { 171 if (i == index) { 172 ret = v; 173 break; 174 } 175 i++; 176 } 177 return ret; 178 } 179 } 180 /*保留两位小数 181 * 数字字符串保留两位小数 182 * str:数字字符串 183 * num:保留小数的位数,默认为2 184 * isCarry:是否进位,默认尝试进位 185 * 分为两种方式,一个是尝试进位的方式保留两位小数,另外一种是不管能否进位,直接截断,以达到保留两位小数的目的,若是原字符串长度不够,比如传递过来0.9这样的,那么会原样返回。 186 */ 187 std::wstring two_decimal_places(const std::wstring& str, unsigned num = 2, bool isCarry = true); 188 /*检查给定值是否在后者中;若是存在,则返回给定值所在的下标(从0开始),否则返回-1 189 * T1元素位于T2中,比如:T1是int,那么T2应该是stl中的某种容器,比如vector<int> 190 */ 191 template<typename T1, typename T2> 192 int isExist(T1 t1, T2 t2) { 193 bool flag{}; 194 int index{}; 195 for (auto& v : t2) { 196 if (t1 == v) { 197 flag = true; 198 return index; 199 } 200 index++; 201 } 202 if (!flag) { 203 return -1; 204 } 205 else { 206 return index; 207 } 208 } 209 /* 210 * wstring版本的replace函数,主要是实现在给定的范围内,将replaced_str替换成value_str,is_all表示是否替换所有的replaced_str; 211 * 注:是直接在源字符串上操作; 212 * str:源字符串 213 * first:size_t,指向开始范围; 214 * strLen:size_t,范围的长度; 215 * replaced_str:被替换的字符(串) 216 * value_str:目标字符(串) 217 * is_all:为true时表示替换给定范围内的所有replaced_str;为false的时候表示只替换一次(如果存在匹配); 218 */ 219 std::wstring& replace(std::wstring& str, size_t first, size_t strLen, const std::wstring replaced_str, const std::wstring value_str, bool is_all); 220 /* 221 * string版本的replace函数,主要是实现在给定的范围内,将replaced_str替换成value_str,is_all表示是否替换所有的replaced_str; 222 * 注:并不直接修改源字符串 223 * str:源字符串 224 * first:size_t,指向开始范围; 225 * strLen:size_t,范围的长度; 226 * replaced_str:被替换的字符(串) 227 * value_str:目标字符(串) 228 * is_all:为true时表示替换给定范围内的所有replaced_str;为false的时候表示只替换一次(如果存在匹配); 229 */ 230 std::string replace(std::string& str, size_t first, size_t strLen, const std::string replaced_str, const std::string value_str, bool is_all); 231 /* 232 * 循环左移函数:将数字类型的变量类型(int,long,long long等)的二进制循环左移 233 * 注:只针对基础类型,不支持对象类型 234 * source:被循环左移的变量 235 * num:循环的位数,你应该确保num小于source的二进制位数 236 */ 237 template<typename T> 238 T ring_shift_left(T source, int num) { 239 int binary_len = sizeof(T) * 8; 240 if (binary_len == num) { 241 return source; 242 } 243 else if (binary_len < num) 244 { 245 num = num % binary_len; 246 } 247 248 T a = source << num; 249 T b = source >> (binary_len - num); 250 T result = a | b; 251 return result; 252 } 253 254 /* 255 * vector<char>转为string 256 */ 257 std::string vecChar_to_string(std::vector<char>& source); 258 /* 259 * vector<unsigned char>转为string 260 */ 261 std::string vecUChar_to_string(std::vector<unsigned char>& source); 262 263 /* 264 * 打印可选普通字符串optstr后,跟集合的所有元素(要求能使用cout正常输出的),并用指定的字符分隔在一行中 265 * coll:待输出的元素集合 266 * delimiter:分隔符 267 * optstr:说明字符串 268 */ 269 template<typename T> 270 inline void PRINT_ELEMENTS(const T& coll, const std::string& delimiter = "", const std::string& optstr = "") { 271 std::cout << optstr; 272 for (const auto& elem : coll) { 273 std::cout << elem << delimiter; 274 } 275 std::cout << std::endl; 276 } 277 /* 278 * 打印可选宽字符串optstr后,跟集合的所有元素(要求能使用wcout正常输出的),并用指定的字符分隔在一行中 279 * coll:待输出的元素集合 280 * delimiter:分隔符 281 * optstr:说明字符串 282 */ 283 template<typename T> 284 inline void PRINT_ELEMENTS_W(const T& coll, const std::wstring& delimiter = L"", const std::wstring& optstr = L"") { 285 std::locale::global(std::locale("")); //本地化 286 std::wcout << optstr; 287 for (const auto& elem : coll) { 288 std::wcout << elem << delimiter; 289 } 290 std::wcout << std::endl; 291 } 292 /* 293 * stirng转wstring 294 */ 295 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::wstring string2wstring(std::string str); 296 /* 297 * wstring转string 298 */ 299 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::string wstring2string(std::wstring wstr); 300 /* 301 * 字符串转数字,单个转换版本; 302 * 本函数会尽可能将字符转换为数字,若是所遇的第一个字符不是标明的忽略字符,将转换失败,设置result参数为false。 303 * source:待转换的字符 304 * neglect:需要忽略的开头的字符 305 * result:标志本次转换是否成功 306 * hexadecimal:进制数,默认为10 307 * 返回值:返回成功转换的结果数值,若是转换失败,返回值为0; 308 * 注:应该在函数执行完成后,检查result参数的值,为true表示成功,否则表示失败 309 * 开头的空白符会自动跳过 310 */ 311 long long string_to_value(const std::string source, std::string neglect, bool* result, unsigned hexadecimal = 10); 312 313 //将string转换为wstring 314 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::wstring to_wstring(const std::string& str, const std::locale& loc = std::locale()); 315 //将wstring转换为string,使用'?`作为默认字符 316 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::string to_string(const std::wstring& str, const std::locale& loc = std::locale()); 317 //转换UTF-8字符串为wstring 318 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::wstring utf8_to_wstring(const std::string& str); 319 //将wstring转换为UTF-8字符串 320 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::string wstring_to_utf8(const std::wstring& str); 321 /* 322 * 删除字符串开头的空格,制表符 323 */ 324 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::string remove_leading_whitespace(std::string str); 325 /* 326 * 删除字符串开头的空格,制表符 327 */ 328 [[nodiscard("不可以忽略该函数的返回值,否则函数动作无效")]] std::wstring remove_leading_whitespace(std::wstring str); 329 } 330 331 #endif // !MY_FUNCTION_H_
my_function.cpp

1 #include "my_function.h" 2 3 namespace MY_TOOLS { 4 int in_double(double& result_int, const char* hint_str, const char* error_message) { 5 double a; 6 while (true) 7 { 8 std::cout << hint_str; 9 10 if (std::cin >> a) { 11 std::cin.get(); //cin不处理回车符 12 result_int = a; 13 break; 14 } 15 else { 16 if (nullptr != error_message) { 17 std::cout << error_message; 18 } 19 std::cin.clear(); 20 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 21 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 22 // 通过 numeric_limits 模板的特化提供此信息。 23 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 24 } 25 } 26 return EXIT_SUCCESS; 27 } 28 int in_charArray(char* result_str, unsigned int len, const char* hint_str, const char* error_message) { 29 std::string a; 30 if (UINT_MAX == len) { 31 std::cout << "参数len的值为UINT_MAX!"; 32 return EXIT_FAILURE; 33 } 34 while (true) 35 { 36 std::cout << hint_str; 37 38 if (std::getline(std::cin, a)) { 39 if (a.size() <= len) { 40 const char* b = a.c_str(); 41 strncpy_s(result_str, len + 1, b, len); 42 /* 43 * errno_t strncpy_s( char *strDest, size_t numberOfElements, const char *strSource, size_t count); 44 * 函数在内部处理的时候,会因为要保留NULL字符,将numberOfElements减去1,就是说,numberOfElements最小值应该为2,否则就会触发参数无效异常 45 */ 46 *(result_str + len) = NULL; 47 break; 48 } 49 else { 50 if (nullptr == error_message) { 51 std::cout << "你输入的字符串太长了,超过了" << len << "。重新输入。" << std::endl; 52 a = ""; 53 } 54 else { 55 std::cout << error_message; 56 a = ""; 57 } 58 59 } 60 } 61 else { 62 //对于输入字符类型,这个应该是有点多余的。 63 std::cin.clear(); 64 //std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 ,但是若是输入缓冲区为空,就会阻塞,等待缓冲区有值才会执行。 65 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 66 // 通过 numeric_limits 模板的特化提供此信息。 67 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 68 } 69 } 70 return EXIT_SUCCESS; 71 } 72 int in_uint(unsigned int& result_int, const char* hint_str, const char* error_message) { 73 long long a; 74 while (true) 75 { 76 std::cout << hint_str; 77 78 if (std::cin >> a) { 79 std::cin.get(); //cin不处理回车符 80 if (a >= 0 && a <= UINT_MAX) { 81 result_int = static_cast<unsigned int>(a); 82 break; 83 } 84 } 85 else { 86 std::cin.clear(); 87 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 88 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 89 // 通过 numeric_limits 模板的特化提供此信息。 90 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 91 } 92 if (nullptr == error_message) { 93 std::cout << "请输入正整数!\n"; 94 } 95 else { 96 std::cout << error_message; 97 } 98 } 99 return EXIT_SUCCESS; 100 } 101 int in_int(int& result_int, const char* hint_str, const char* error_message) { 102 int a; 103 while (true) 104 { 105 std::cout << hint_str; 106 107 if (std::cin >> a) { 108 result_int = a; 109 std::cin.get(); //cin不处理回车符 110 break; 111 } 112 else { 113 std::cin.clear(); 114 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 115 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 116 // 通过 numeric_limits 模板的特化提供此信息。 117 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 118 } 119 if (nullptr == error_message) { 120 std::cout << "请输入整数!"; 121 } 122 else { 123 std::cout << error_message; 124 } 125 } 126 return EXIT_SUCCESS; 127 } 128 std::string format(const std::string str, ...) { 129 va_list args; 130 va_start(args, str); 131 std::string result_str = str; 132 size_t index = result_str.find("{}", 0); 133 const char* value{}; 134 while (index != std::string::npos) 135 { 136 value = va_arg(args, const char*); 137 138 result_str.replace(index, 2, value); 139 140 index = result_str.find("{}", 0); 141 } 142 va_end(args); 143 144 return result_str; 145 } 146 147 long in_long(long& result_int, const char* hint_str, const char* error_message) { 148 long a; 149 while (true) 150 { 151 std::cout << hint_str; 152 153 if (std::cin >> a) { 154 result_int = a; 155 std::cin.get(); //cin不处理回车符 156 break; 157 } 158 else { 159 std::cin.clear(); 160 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 161 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 162 // 通过 numeric_limits 模板的特化提供此信息。 163 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 164 } 165 if (nullptr == error_message) { 166 std::cout << "请输入整数!"; 167 } 168 else { 169 std::cout << error_message; 170 } 171 } 172 return EXIT_SUCCESS; 173 } 174 int in_uint_scope(unsigned int& result_int, unsigned int start_num, unsigned int end_num, const char* hint_str, const char* error_message) { 175 if (start_num < end_num) { 176 unsigned int a; 177 while (true) 178 { 179 std::cout << hint_str; 180 if (std::cin >> a) { 181 if (start_num <= a && a <= end_num) { 182 result_int = a; 183 std::cin.get(); //cin不处理回车符 184 break; 185 } 186 else { 187 std::wcout << L"输入的值应该大于等于" << start_num << L"小于等于" << end_num << L"!\n"; 188 std::cin.get(); //cin不处理回车符 189 continue; 190 } 191 } 192 else { 193 std::cin.clear(); 194 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 195 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 196 // 通过 numeric_limits 模板的特化提供此信息。 197 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 198 } 199 if (nullptr == error_message) { 200 std::cout << "请输入整数!"; 201 } 202 else { 203 std::cout << error_message; 204 } 205 } 206 return EXIT_SUCCESS; 207 } 208 else { 209 throw L"起始值大于等于截止值!"; 210 //std::wcout << L"起始值大于等于截止值!" << std::endl; 211 return EXIT_SUCCESS; 212 } 213 } 214 int in_char(char& result_char, const char* hint_str, const char* error_message) { 215 std::string a; 216 while (true) 217 { 218 std::cout << hint_str; 219 220 if (std::getline(std::cin, a)) { 221 result_char = a[0]; 222 break; 223 } 224 else { 225 std::cin.clear(); 226 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 227 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 228 // 通过 numeric_limits 模板的特化提供此信息。 229 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 230 } 231 if (nullptr == error_message) { 232 std::cout << "请输入!"; 233 } 234 else { 235 std::cout << error_message; 236 } 237 } 238 return EXIT_SUCCESS; 239 } 240 int in_wchar_t(wchar_t& result_char, const wchar_t* hint_str, const wchar_t* error_message) { 241 std::wstring a; 242 while (true) 243 { 244 std::wcout << hint_str; 245 246 if (std::getline(std::wcin, a)) { 247 a += L'\n'; //不能丢弃换行符,因为有时候就是需要它。 248 result_char = a[0]; 249 break; 250 } 251 else { 252 std::cin.clear(); 253 std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');//清除输入缓冲区的当前行 254 //numeric_limits:numeric_limits 类模板提供查询各种算术类型属性的标准化方式(例如 int 类型的最大可能值是 std::numeric_limits<int>::max() )。 255 // 通过 numeric_limits 模板的特化提供此信息。 256 //streamsize:类型 std::streamsize 是用于表示 I/O 操作中转移字符数或 I/O 缓冲区的大小,是有符号整数类型。 257 } 258 if (nullptr == error_message) { 259 std::wcout << L"请输入!"; 260 } 261 else { 262 std::wcout << error_message; 263 } 264 } 265 return EXIT_SUCCESS; 266 } 267 std::list<std::string>split(const std::string value, char character, size_t len) { 268 std::list<std::string> ret; 269 unsigned start_index{}, end_index{}; 270 for (unsigned i{}; i < len; i++) { 271 end_index = i; 272 if (value[i] == character) { 273 ret.push_back(value.substr(start_index, end_index - start_index)); 274 start_index = end_index + 1; 275 } 276 } 277 ret.push_back(value.substr(start_index, len - start_index)); 278 return ret; 279 } 280 281 std::list<std::wstring>split(const std::wstring value, wchar_t character, size_t len) { 282 std::list<std::wstring> ret; 283 unsigned start_index{}, end_index{}; 284 for (unsigned i{}; i < len; i++) { 285 end_index = i; 286 if (value[i] == character) { 287 ret.push_back(value.substr(start_index, end_index - start_index)); 288 start_index = end_index + 1; 289 } 290 } 291 ret.push_back(value.substr(start_index, len - start_index)); 292 return ret; 293 } 294 std::vector<std::wstring>split_vector(std::wstring& value, wchar_t character, size_t len) { 295 std::vector<std::wstring> ret; 296 unsigned start_index{}, end_index{}; 297 for (unsigned i{}; i < len; i++) { 298 end_index = i; 299 if (value[i] == character) { 300 ret.push_back(value.substr(start_index, end_index - start_index)); 301 start_index = end_index + 1; 302 } 303 } 304 ret.push_back(value.substr(start_index, len - start_index)); 305 return ret; 306 } 307 std::vector<std::wstring>split_vector(const wchar_t* value, wchar_t character, size_t len) { 308 std::vector<std::wstring> ret; 309 unsigned start_index{}, end_index{}; 310 std::wstring value_str = value; 311 for (unsigned i{}; i < len; i++) { 312 end_index = i; 313 if (value[i] == character) { 314 ret.push_back(value_str.substr(start_index, end_index - start_index)); 315 start_index = end_index + 1; 316 } 317 } 318 ret.push_back(value_str.substr(start_index, len - start_index)); 319 return ret; 320 } 321 std::wstring two_decimal_places(const std::wstring& str, unsigned num, bool isCarry) { 322 std::wstring cost = str; 323 324 size_t str_index = cost.find('.'); 325 if (str_index != std::wstring::npos) { 326 if (isCarry) { 327 if ((str_index + num + 1) < cost.size()) { 328 //长度足够 329 //尝试进位 330 if (cost[str_index + num + 1] > L'4') { 331 //进位 332 bool is_carry{}; //是否需要最终进位,比如99.99进位到100.00;true表示要 333 std::wstring cost_ = cost.substr(0, str_index + num + 1); 334 for (auto rend = cost_.rbegin(); rend < cost_.rend(); rend++) { 335 if (*rend == L'9') { 336 *rend = L'0'; 337 is_carry = true; 338 } 339 else { 340 is_carry = false; 341 *rend = ++(*rend); 342 cost = cost_; 343 break; 344 } 345 } 346 if (is_carry) { 347 cost = L'1' + cost_; 348 } 349 } 350 else { 351 //直接截断,保留两位小数 352 cost = cost.substr(0, str_index + 3); 353 } 354 } 355 else { 356 //长度不足 357 ; 358 } 359 } 360 else { 361 if ((str_index + num + 1) < cost.size()) { 362 cost = cost.substr(0, str_index + 3); 363 } 364 } 365 } 366 return cost; 367 } 368 369 std::wstring& replace(std::wstring& str, size_t first, size_t strLen, const std::wstring replaced_str, const std::wstring value_str, bool is_all) { 370 std::wstring result = str.substr(first, strLen); 371 if (is_all) { 372 size_t index{}; 373 index = result.find(replaced_str, index); 374 size_t replaced_str_len = replaced_str.size(); 375 while (index != std::wstring::npos) 376 { 377 result.replace(index, replaced_str_len, value_str); 378 index += value_str.length(); //主要是为了防止出现循环替换的情况 379 index = result.find(replaced_str, index); 380 } 381 str.replace(first, strLen, result); 382 return str; 383 } 384 else { 385 size_t index = result.find(replaced_str); 386 if (index != std::wstring::npos) { 387 size_t replaced_str_len = replaced_str.size(); 388 result.replace(index, replaced_str_len, value_str); 389 str.replace(first, strLen, result); 390 } 391 return str; 392 } 393 } 394 std::string replace(std::string& str, size_t first, size_t strLen, const std::string replaced_str, const std::string value_str, bool is_all) { 395 std::string str_sub = str.substr(first, strLen); 396 if (is_all) { 397 size_t index{}; 398 index = str_sub.find(replaced_str, index); 399 while (index != std::wstring::npos) 400 { 401 str_sub.replace(index, replaced_str.size(), value_str); 402 index += value_str.length(); //主要是为了防止出现循环替换的情况 403 index = str_sub.find(replaced_str, index); 404 } 405 } 406 else { 407 //只替换一次 408 size_t index = str_sub.find(replaced_str); 409 if (index != std::wstring::npos) { 410 size_t replaced_str_len = replaced_str.size(); 411 str_sub.replace(index, replaced_str_len, value_str); 412 } 413 } 414 return str_sub; 415 416 } 417 std::string vecChar_to_string(std::vector<char>& source) { 418 std::string ret; 419 for (auto& v : source) { 420 ret += static_cast<char>(v); 421 } 422 return ret; 423 } 424 std::string vecUChar_to_string(std::vector<unsigned char>& source) { 425 std::string ret; 426 for (auto& v : source) { 427 ret += static_cast<unsigned char>(v); 428 } 429 return ret; 430 } 431 std::wstring string2wstring(std::string str) { 432 std::wstring result; 433 int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, static_cast<int>(0)); 434 if (len < 0)return result; 435 wchar_t* buffer = new wchar_t[len + 1]; 436 if (buffer == NULL)return result; 437 MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, static_cast<int>(len)); 438 buffer[len] = '\0'; 439 result.append(buffer); 440 delete[] buffer; 441 442 return result; 443 } 444 std::string wstring2string(std::wstring wstr) 445 { 446 std::string result; 447 int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL); 448 if (len <= 0)return result; 449 char* buffer = new char[len + 1]; 450 if (buffer == NULL)return result; 451 WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL); 452 buffer[len] = '\0'; 453 result.append(buffer); 454 delete[] buffer; 455 456 return result; 457 } 458 long long string_to_value(const std::string source, std::string neglect, bool* result, unsigned hexadecimal) { 459 long long ret{}; 460 std::string data, temp; 461 //删除前面的空格 462 unsigned i{}; 463 for (; i < source.size(); ++i) { 464 if (source[i] != ' ') { 465 break; 466 } 467 } 468 temp = source.substr(i, source.size() - i); 469 470 if (temp.size() >= neglect.size()) { 471 unsigned i{}; 472 for (; i < neglect.size() && temp[i] == neglect[i]; ++i) { 473 ; 474 } 475 if (i + 1 == neglect.size()) { 476 //前缀符合 477 data = temp.substr(neglect.size(), temp.size() - neglect.size()); 478 } 479 else { 480 data = temp; 481 } 482 } 483 else { 484 *result = false; 485 return 0; 486 } 487 try 488 { 489 ret = std::stoll(data, nullptr, hexadecimal); 490 *result = true; 491 } 492 catch (const std::exception& e) 493 { 494 *result = false; 495 return 0; 496 } 497 return ret; 498 } 499 std::wstring to_wstring(const std::string& str, const std::locale& loc) { 500 std::vector<wchar_t>buf(str.size()); 501 std::use_facet<std::ctype<wchar_t>>(loc).widen(str.data(), str.data() + str.size(), buf.data()); 502 return std::wstring(buf.data(), buf.size()); 503 } 504 std::string to_string(const std::wstring& str, const std::locale& loc) { 505 std::vector<char>buf(str.size()); 506 std::use_facet<std::ctype<wchar_t>>(loc).narrow(str.data(), str.data() + str.size(), '?', buf.data()); 507 return std::string(buf.data(), buf.size()); 508 } 509 std::wstring utf8_to_wstring(const std::string& str) { 510 std::wstring_convert<std::codecvt_utf8 < wchar_t > >myconv; 511 return myconv.from_bytes(str); 512 } 513 std::string wstring_to_utf8(const std::wstring& str) 514 { 515 std::wstring_convert<std::codecvt_utf8 < wchar_t > >myconv; 516 return myconv.to_bytes(str); 517 } 518 519 std::string remove_leading_whitespace(std::string str) { 520 std::string ret; 521 size_t i{}; 522 for (; i < str.size(); ++i) { 523 if (str[i] != ' ' || str[i] != '\t') { 524 break; 525 } 526 } 527 ret = str.substr(i, str.size() - i); 528 return ret; 529 } 530 std::wstring remove_leading_whitespace(std::wstring str) { 531 std::wstring ret; 532 size_t i{}; 533 for (; i < str.size(); ++i) { 534 if (str[i] != L' ' || str[i] != L'\t') { 535 break; 536 } 537 } 538 ret = str.substr(i, str.size() - i); 539 return ret; 540 } 541 }
不定期更新。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?