Console Library 8.0.0
A header-only library that makes C++ simple
Loading...
Searching...
No Matches
strpp.h
Go to the documentation of this file.
1
10
11/*
12Copyright (c) 2026 MrXie1109
13
14Permission is hereby granted, free of charge, to any person obtaining a copy
15of this software and associated documentation files (the "Software"), to deal
16in the Software without restriction, including without limitation the rights
17to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18copies of the Software, and to permit persons to whom the Software is
19furnished to do so, subject to the following conditions:
20
21The above copyright notice and this permission notice shall be included in all
22copies or substantial portions of the Software.
23
24THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30SOFTWARE.
31*/
32
33#pragma once
34#include <algorithm>
35#include <cctype>
36#include <climits>
37#include <clocale>
38#include <cstdint>
39#include <initializer_list>
40#include <iostream>
41#include <locale>
42#include <sstream>
43#include <string>
44#include <utility>
45#include <vector>
46
47#include "../core/csexc.h"
48
49namespace console {
55
64 template <class CharT, class Traits, class Allocator>
65 std::basic_string<CharT, Traits, Allocator>
66 ltrim(std::basic_string<CharT, Traits, Allocator> str) {
67 auto it = std::find_if(str.begin(),
68 str.end(),
69 [](unsigned char uc) -> bool { return !isspace(uc); });
70 str.erase(str.begin(), it);
71 return str;
72 }
73
82 template <class CharT, class Traits, class Allocator>
83 std::basic_string<CharT, Traits, Allocator>
84 rtrim(std::basic_string<CharT, Traits, Allocator> str) {
85 auto it = std::find_if(str.rbegin(),
86 str.rend(),
87 [](unsigned char uc) -> bool { return !isspace(uc); });
88 str.erase(it.base(), str.end());
89 return str;
90 }
91
100 template <class CharT, class Traits, class Allocator>
101 std::basic_string<CharT, Traits, Allocator>
102 trim(std::basic_string<CharT, Traits, Allocator> str) {
103 auto front = std::find_if(str.begin(),
104 str.end(),
105 [](unsigned char uc) -> bool { return !isspace(uc); });
106 if (front == str.end()) {
107 str.clear();
108 return str;
109 }
110 auto back = std::find_if(str.rbegin(),
111 str.rend(),
112 [](unsigned char uc) -> bool { return !isspace(uc); });
113 str.erase(back.base(), str.end());
114 str.erase(str.begin(), front);
115 return str;
116 }
117
127 template <class CharT, class Traits, class Allocator>
128 std::basic_string<CharT, Traits, Allocator>
129 ltrim(std::basic_string<CharT, Traits, Allocator> str,
130 const std::basic_string<CharT, Traits, Allocator> &chars) {
131 auto it
132 = std::find_if(str.begin(), str.end(), [&chars](unsigned char ch) {
133 return chars.find(ch)
134 == std::basic_string<CharT, Traits, Allocator>::npos;
135 });
136 str.erase(str.begin(), it);
137 return str;
138 }
139
149 template <class CharT, class Traits, class Allocator>
150 std::basic_string<CharT, Traits, Allocator>
151 rtrim(std::basic_string<CharT, Traits, Allocator> str,
152 const std::basic_string<CharT, Traits, Allocator> &chars) {
153 auto it = std::find_if(
154 str.rbegin(), str.rend(), [&chars](unsigned char ch) {
155 return chars.find(ch)
156 == std::basic_string<CharT, Traits, Allocator>::npos;
157 });
158 str.erase(it.base(), str.end());
159 return str;
160 }
161
171 template <class CharT, class Traits, class Allocator>
172 std::basic_string<CharT, Traits, Allocator>
173 trim(std::basic_string<CharT, Traits, Allocator> str,
174 const std::basic_string<CharT, Traits, Allocator> &chars) {
175 auto front
176 = std::find_if(str.begin(), str.end(), [&chars](unsigned char ch) {
177 return chars.find(ch)
178 == std::basic_string<CharT, Traits, Allocator>::npos;
179 });
180 if (front == str.end()) {
181 str.clear();
182 return str;
183 }
184 auto back = std::find_if(
185 str.rbegin(), str.rend(), [&chars](unsigned char ch) {
186 return chars.find(ch)
187 == std::basic_string<CharT, Traits, Allocator>::npos;
188 });
189 str.erase(back.base(), str.end());
190 str.erase(str.begin(), front);
191 return str;
192 }
193
203 template <class CharT, class Traits, class Allocator>
204 std::basic_string<CharT, Traits, Allocator>
205 upper(std::basic_string<CharT, Traits, Allocator> str,
206 const std::locale &loc = std::locale{}) {
207 for (auto &ch : str) ch = std::toupper(ch, loc);
208 return str;
209 }
210
220 template <class CharT, class Traits, class Allocator>
221 std::basic_string<CharT, Traits, Allocator>
222 lower(std::basic_string<CharT, Traits, Allocator> str,
223 const std::locale &loc = std::locale{}) {
224 for (auto &ch : str) ch = std::tolower(ch, loc);
225 return str;
226 }
227
237 template <class CharT, class Traits, class Allocator>
238 std::basic_string<CharT, Traits, Allocator>
239 title(std::basic_string<CharT, Traits, Allocator> str,
240 const std::locale &loc = std::locale{}) {
241 using string_type = std::basic_string<CharT, Traits, Allocator>;
242 if (str.empty()) return string_type{};
243 str[0] = std::toupper(str[0], loc);
244 for (size_t i = 1; i < str.size(); ++i) {
245 if (std::isspace(str[i - 1], loc))
246 str[i] = std::toupper(str[i], loc);
247 else
248 str[i] = std::tolower(str[i], loc);
249 }
250 return str;
251 }
252
260 template <class CharT = char,
261 class Traits = std::char_traits<CharT>,
262 class Allocator = std::allocator<CharT>>
264 using string_type = std::basic_string<CharT, Traits, Allocator>;
265
269
276 friend std::basic_ostream<CharT, Traits> &
277 operator<<(std::basic_ostream<CharT, Traits> &os,
278 const BasicPartitionResult &pr) {
279 return os << "BasicPartitionResult(\"" << pr.left << "\", \""
280 << pr.middle << "\", \"" << pr.right << "\")";
281 }
282 };
283
288
299 template <class CharT, class Traits, class Allocator>
301 partition(const std::basic_string<CharT, Traits, Allocator> &text,
302 const std::basic_string<CharT, Traits, Allocator> &sep) {
303 using string_type = std::basic_string<CharT, Traits, Allocator>;
304 size_t pos = text.find(sep);
305 if (pos == string_type::npos)
307 text, string_type{}, string_type{}};
309 text.substr(0, pos), sep, text.substr(pos + sep.size())};
310 }
311
322 template <class CharT, class Traits, class Allocator>
323 std::vector<std::basic_string<CharT, Traits, Allocator>>
324 split(const std::basic_string<CharT, Traits, Allocator> &text,
325 const std::basic_string<CharT, Traits, Allocator> &sep
326 = std::basic_string<CharT, Traits, Allocator>(1, CharT{' '})) {
327 using string_type = std::basic_string<CharT, Traits, Allocator>;
328 using vector_type = std::vector<string_type>;
329 vector_type result;
330 if (sep.empty()) return {text};
331 size_t start = 0;
332 while (start <= text.size()) {
333 size_t pos = text.find(sep, start);
334 if (pos == string_type::npos) {
335 result.push_back(text.substr(start));
336 break;
337 }
338 result.push_back(text.substr(start, pos - start));
339 start = pos + sep.size();
340 }
341 return result;
342 }
343
354 template <class T,
355 class CharT = char,
356 class Traits = std::char_traits<CharT>,
357 class Allocator = std::allocator<CharT>>
358 std::basic_string<CharT, Traits, Allocator> join(const std::vector<T> &vec,
359 const std::basic_string<CharT, Traits, Allocator> &sep
360 = std::basic_string<CharT, Traits, Allocator>{}) {
361 using string_type = std::basic_string<CharT, Traits, Allocator>;
362 if (vec.empty()) return string_type{};
363 std::basic_ostringstream<CharT, Traits> ss;
364 auto it = vec.begin();
365 ss << *it;
366 while (++it != vec.end()) ss << sep << *it;
367 return ss.str();
368 }
369
371 inline std::string ltrim(const char *str) {
372 return ltrim(std::string(str));
373 }
374
375 inline std::wstring ltrim(const wchar_t *str) {
376 return ltrim(std::wstring(str));
377 }
378
380 inline std::string rtrim(const char *str) {
381 return rtrim(std::string(str));
382 }
383
384 inline std::wstring rtrim(const wchar_t *str) {
385 return rtrim(std::wstring(str));
386 }
387
389 inline std::string trim(const char *str) {
390 return trim(std::string(str));
391 }
392
393 inline std::wstring trim(const wchar_t *str) {
394 return trim(std::wstring(str));
395 }
396
398 inline std::string ltrim(const char *str, const std::string &chars) {
399 return ltrim(std::string(str), chars);
400 }
401
402 inline std::wstring ltrim(const wchar_t *str, const std::wstring &chars) {
403 return ltrim(std::wstring(str), chars);
404 }
405
407 inline std::string rtrim(const char *str, const std::string &chars) {
408 return rtrim(std::string(str), chars);
409 }
410
411 inline std::wstring rtrim(const wchar_t *str, const std::wstring &chars) {
412 return rtrim(std::wstring(str), chars);
413 }
414
416 inline std::string trim(const char *str, const std::string &chars) {
417 return trim(std::string(str), chars);
418 }
419
420 inline std::wstring trim(const wchar_t *str, const std::wstring &chars) {
421 return trim(std::wstring(str), chars);
422 }
423
425 inline std::string ltrim(const char *str, const char *chars) {
426 return ltrim(std::string(str), std::string(chars));
427 }
428
429 inline std::wstring ltrim(const wchar_t *str, const wchar_t *chars) {
430 return ltrim(std::wstring(str), std::wstring(chars));
431 }
432
434 inline std::string rtrim(const char *str, const char *chars) {
435 return rtrim(std::string(str), std::string(chars));
436 }
437
438 inline std::wstring rtrim(const wchar_t *str, const wchar_t *chars) {
439 return rtrim(std::wstring(str), std::wstring(chars));
440 }
441
443 inline std::string trim(const char *str, const char *chars) {
444 return trim(std::string(str), std::string(chars));
445 }
446
447 inline std::wstring trim(const wchar_t *str, const wchar_t *chars) {
448 return trim(std::wstring(str), std::wstring(chars));
449 }
450
452 inline std::string ltrim(const std::string &str, const char *chars) {
453 return ltrim(str, std::string(chars));
454 }
455
456 inline std::wstring ltrim(const std::wstring &str, const wchar_t *chars) {
457 return ltrim(str, std::wstring(chars));
458 }
459
461 inline std::string rtrim(const std::string &str, const char *chars) {
462 return rtrim(str, std::string(chars));
463 }
464
465 inline std::wstring rtrim(const std::wstring &str, const wchar_t *chars) {
466 return rtrim(str, std::wstring(chars));
467 }
468
470 inline std::string trim(const std::string &str, const char *chars) {
471 return trim(str, std::string(chars));
472 }
473
474 inline std::wstring trim(const std::wstring &str, const wchar_t *chars) {
475 return trim(str, std::wstring(chars));
476 }
477
479 inline std::string
480 upper(const char *str, const std::locale &loc = std::locale{}) {
481 return upper(std::string(str), loc);
482 }
483
484 inline std::wstring
485 upper(const wchar_t *str, const std::locale &loc = std::locale{}) {
486 return upper(std::wstring(str), loc);
487 }
488
489 inline std::string
490 lower(const char *str, const std::locale &loc = std::locale{}) {
491 return lower(std::string(str), loc);
492 }
493
494 inline std::wstring
495 lower(const wchar_t *str, const std::locale &loc = std::locale{}) {
496 return lower(std::wstring(str), loc);
497 }
498
500 inline std::string
501 title(const char *str, const std::locale &loc = std::locale{}) {
502 return title(std::string(str), loc);
503 }
504
505 inline std::wstring
506 title(const wchar_t *str, const std::locale &loc = std::locale{}) {
507 return title(std::wstring(str), loc);
508 }
509
511 template <class CharT, class Traits, class Allocator>
513 partition(const std::basic_string<CharT, Traits, Allocator> &text,
514 const CharT *sep) {
515 return partition(
516 text, std::basic_string<CharT, Traits, Allocator>(sep));
517 }
518
520 template <class CharT, class Traits, class Allocator>
521 std::vector<std::basic_string<CharT, Traits, Allocator>>
522 split(const std::basic_string<CharT, Traits, Allocator> &text,
523 const CharT *sep) {
524 return split(text, std::basic_string<CharT, Traits, Allocator>(sep));
525 }
526
528 inline BasicPartitionResult<>
529 partition(const char *text, const std::string &sep) {
530 return partition(std::string(text), sep);
531 }
532
533 inline BasicPartitionResult<wchar_t>
534 partition(const wchar_t *text, const std::wstring &sep) {
535 return partition(std::wstring(text), sep);
536 }
537
539 inline std::vector<std::string>
540 split(const char *text, const std::string &sep = " ") {
541 return split(std::string(text), sep);
542 }
543
544 inline std::vector<std::wstring>
545 split(const wchar_t *text, const std::wstring &sep = L" ") {
546 return split(std::wstring(text), sep);
547 }
548
550 inline std::string
551 join(const std::vector<std::string> &items, const std::string &sep = "") {
552 std::string result;
553 for (const auto &item : items) {
554 if (!result.empty()) result += sep;
555 result += item;
556 }
557 return result;
558 }
559
560 inline std::wstring join(
561 const std::vector<std::wstring> &items, const std::wstring &sep = L"") {
562 std::wstring result;
563 for (const auto &item : items) {
564 if (!result.empty()) result += sep;
565 result += item;
566 }
567 return result;
568 }
569
573 template <class CharT, class Traits>
574 inline void to_stream(char ch, std::basic_ostream<CharT, Traits> &os) {
575 os << ch;
576 }
577
581 template <class CharT, class Traits>
582 inline void to_stream(wchar_t wch, std::basic_ostream<CharT, Traits> &os) {
583 os << std::wcout.narrow(wch, '?');
584 }
585
589 template <class Traits>
590 inline void
591 to_stream(wchar_t wch, std::basic_ostream<wchar_t, Traits> &os) {
592 os << wch;
593 }
594
598 template <class CharT, class Traits>
599 inline void
600 to_stream(const std::string &str, std::basic_ostream<CharT, Traits> &os) {
601 os << str.c_str();
602 }
603
607 template <class CharT, class Traits>
608 inline void
609 to_stream(const std::wstring &wstr, std::basic_ostream<CharT, Traits> &os) {
610 for (wchar_t wch : wstr) to_stream(wch, os);
611 }
612
616 template <class CharT, class Traits>
617 inline void
618 to_stream(const char *str, std::basic_ostream<CharT, Traits> &os) {
619 if (str == nullptr) return;
620 os << str;
621 }
622
626 template <class CharT, class Traits>
627 inline void
628 to_stream(const wchar_t *wstr, std::basic_ostream<CharT, Traits> &os) {
629 for (const wchar_t *p = wstr; p && *p; ++p) to_stream(*p, os);
630 }
631
632 template <class CharT, class Traits, std::size_t N>
633 inline void
634 to_stream(char (&arr)[N], std::basic_ostream<CharT, Traits> &os) {
635 to_stream(static_cast<const char *>(arr), os);
636 }
637
638 template <class CharT, class Traits, std::size_t N>
639 inline void
640 to_stream(wchar_t (&arr)[N], std::basic_ostream<CharT, Traits> &os) {
641 to_stream(static_cast<const wchar_t *>(arr), os);
642 }
643
644 template <class CharT, class Traits, class T>
645 inline typename std::enable_if<
646 !std::is_same<typename std::decay<T>::type, char>::value && //
647 !std::is_same<typename std::decay<T>::type, wchar_t>::value && //
648 !std::is_same<typename std::decay<T>::type, char *>::value && //
649 !std::is_same<typename std::decay<T>::type, wchar_t *>::value && //
650 !std::is_same<typename std::decay<T>::type, std::string>::value && //
651 !std::is_same<typename std::decay<T>::type, std::wstring>::value //
652 >::type
653 to_stream(T &&value, std::basic_ostream<CharT, Traits> &os) {
654 os << std::forward<T>(value);
655 }
656
663 template <class... Args>
664 std::string to_string(Args &&...args) {
665 std::ostringstream oss;
666 int _[] = {0, (to_stream(args, oss), 0)...};
667 (void)_;
668 return oss.str();
669 }
670
680 template <class CharT, class Traits, class Allocator, class... Args>
682 std::basic_string<CharT, Traits, Allocator> str, Args &...args) {
683 std::basic_istringstream<CharT, Traits> iss(str);
684 int _[] = {0, (iss >> args, 0)...};
685 (void)_;
686 }
687 // end of strpp group
689}
定义 console 库使用的自定义异常类层次结构。
std::vector< std::basic_string< CharT, Traits, Allocator > > split(const std::basic_string< CharT, Traits, Allocator > &text, const std::basic_string< CharT, Traits, Allocator > &sep=std::basic_string< CharT, Traits, Allocator >(1, CharT{' '}))
以分隔符分割字符串(类似 Python 的 split,默认按空格分割)。
Definition strpp.h:324
BasicPartitionResult< wchar_t > WPartitionResult
BasicPartitionResult<wchar_t> 的类型别名。
Definition strpp.h:287
std::basic_string< CharT, Traits, Allocator > title(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为标题格式(每个单词首字母大写,其余小写)。
Definition strpp.h:239
BasicPartitionResult< char > PartitionResult
BasicPartitionResult<char> 的类型别名。
Definition strpp.h:285
void to_stream(char ch, std::basic_ostream< CharT, Traits > &os)
将 ch 输出到流。
Definition strpp.h:574
std::basic_string< CharT, Traits, Allocator > join(const std::vector< T > &vec, const std::basic_string< CharT, Traits, Allocator > &sep=std::basic_string< CharT, Traits, Allocator >{})
以分隔符连接容器中的字符串元素。
Definition strpp.h:358
std::basic_string< CharT, Traits, Allocator > trim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串两侧的空白字符。
Definition strpp.h:102
BasicPartitionResult< CharT, Traits, Allocator > partition(const std::basic_string< CharT, Traits, Allocator > &text, const std::basic_string< CharT, Traits, Allocator > &sep)
在字符串中查找第一个分隔符,并返回分隔符之前、分隔符本身、分隔符之后的三部分。
Definition strpp.h:301
std::string to_string(Args &&...args)
将任意多个参数转换为字符串并拼接(无分隔符)。
Definition strpp.h:664
std::basic_string< CharT, Traits, Allocator > upper(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为大写。
Definition strpp.h:205
void from_string(std::basic_string< CharT, Traits, Allocator > str, Args &...args)
将字符串中的值提取到多个参数中,参数类型由调用者指定。
Definition strpp.h:681
std::basic_string< CharT, Traits, Allocator > rtrim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串右侧的空白字符。
Definition strpp.h:84
std::basic_string< CharT, Traits, Allocator > ltrim(std::basic_string< CharT, Traits, Allocator > str)
移除字符串左侧的空白字符(空格、制表符等)。
Definition strpp.h:66
std::basic_string< CharT, Traits, Allocator > lower(std::basic_string< CharT, Traits, Allocator > str, const std::locale &loc=std::locale{})
将字符串转换为小写。
Definition strpp.h:222
本库所有组件所在的顶层命名空间。
@ T
Definition kb.h:99
字符串分区结果,包含左部分、分隔符、右部分。
Definition strpp.h:263
friend std::basic_ostream< char, std::char_traits< char > > & operator<<(std::basic_ostream< char, std::char_traits< char > > &os, const BasicPartitionResult &pr)
Definition strpp.h:277
string_type right
Definition strpp.h:268
std::basic_string< CharT, Traits, Allocator > string_type
Definition strpp.h:264
string_type middle
Definition strpp.h:267
string_type left
Definition strpp.h:266