狂自私

导航

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_
View Code

 

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 }
View Code

 

不定期更新。

posted on 2022-09-22 17:49  狂自私  阅读(53)  评论(0编辑  收藏  举报