0%

cpp字符串操作

1 split

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 将 "aa;bb;cc" 拆分为 ["aa", "bb", "cc"]
std::vector<std::string> split(const std::string &s, const char *delim)
{
std::vector<string> ret;
size_t last = 0;
auto index = s.find(delim, last);
while (index != string::npos)
{
if (index - last > 0)
{
ret.push_back(s.substr(last, index - last));
}
last = index + strlen(delim);
index = s.find(delim, last);
}
if (!s.size() || s.size() - last > 0)
{
ret.push_back(s.substr(last));
}
return ret;
}

2 str_format

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 拼接格式字符串
template <typename... Args>
std::string str_format(const std::string &format, Args... args)
{
#if __cplusplus > 202002L
return std::format(format, args...);
#else
// Calculate the buffer size
auto size_buf = snprintf(nullptr, 0, format.c_str(), args...) + 1;
// Allocate the buffer
#if __cplusplus >= 201703L
// C++17
auto buf = std::make_unique<char[]>(size_buf);
#else
// C++11
std::unique_ptr<char[]> buf(new (std::nothrow) char[size_buf]);
#endif
// Check if the allocation is successful
if (buf == nullptr)
{
return {};
}
// Fill the buffer with formatted string
auto result = snprintf(buf.get(), size_buf, format.c_str(), args...);
// Return the formatted string
return std::string(buf.get(), buf.get() + result);
#endif
}

3 hexstr <—> bin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <string>
#include <sstream>
#include <stdexcept>

// "123456" --> {0x12, 0x34, 0x56}
std::string hexstr2bin(const std::string &hexstr) {
if (hexstr.length() % 2 != 0) {
throw std::logic_error("invalid data len");
}

std::string binstr;

char tmp_v;
for (int i = 0; i < hexstr.length(); i++) {
char ch = hexstr.at(i);
if (!std::isxdigit(ch)) {
std::stringstream ss;
ss << "invalid char:" << ch << ", index:" << i;
throw std::logic_error(ss.str());
}

char v = ch - '0';
if (std::isalpha(ch)) {
v = std::tolower(ch) - 'a' + 10;
}

if (i % 2 == 0) {
tmp_v = v << 4;
} else {
tmp_v += v;
binstr.push_back(tmp_v);
}
}

return binstr;
}

// {0x12, 0x34, 0x56} --> "123456"
std::string bin2hexstr(const std::string &binstr)
{
std::string hexstr;
const char m[] = "0123456789abcdef";

for (uint8_t ch : binstr)
{
hexstr.push_back(m[ch >> 4]);
hexstr.push_back(m[ch & 0x0f]);
}

return hexstr;
}

int main(int argc, char const *argv[])
{
std::string hexstr = "123456abce";
std::string bin = hexstr2bin(hexstr);
std::cout << "===>" << bin2hexstr(bin);
return 0;
}

4. string转map

主要用到 std::getline()std::ws

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <map>
#include <string>
#include <sstream>
#include <iostream>

std::map<std::string, std::string> mappify1(std::string const& s)
{
std::map<std::string, std::string> m;

std::string key, val;
std::istringstream iss(s);

// iss >> std::ws 将流的前导空格去掉
while(std::getline(std::getline(iss >> std::ws, key, ':') >> std::ws, val))
m[key] = val;

return m;
}

std::map<std::string, std::string> mappify2(std::string const& s)
{
std::map<std::string, std::string> m;

std::string::size_type key_pos = 0;
std::string::size_type key_end;
std::string::size_type val_pos;
std::string::size_type val_end;

while((key_end = s.find(':', key_pos)) != std::string::npos)
{
if((val_pos = s.find_first_not_of(": ", key_end)) == std::string::npos)
break;

val_end = s.find('\n', val_pos);
m.emplace(s.substr(key_pos, key_end - key_pos), s.substr(val_pos, val_end - val_pos));

key_pos = val_end;
if(key_pos != std::string::npos)
++key_pos;
}

return m;
}

int main()
{
std::string s = "CA: ABCD\nCB: ABFG\nCC: AFBV\nCD: 4567";

std::cout << "mappify1: " << '\n';

auto m = mappify1(s);
for(auto const& p: m)
std::cout << '{' << p.first << " => " << p.second << '}' << '\n';

std::cout << "mappify2: " << '\n';

m = mappify2(s);
for(auto const& p: m)
std::cout << '{' << p.first << " => " << p.second << '}' << '\n';
}

5. trim std::string

简单的rtirm1

1
2
std::string s
s.earse(s.find_last_not_of(" \n\r\t") + 1);

比较通用的一个https://stackoverflow.com/a/217605

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <algorithm>
#include <cctype>
#include <locale>

// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch);
}));
}

// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch);
}).base(), s.end());
}

// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}

// trim from start (copying)
static inline std::string ltrim_copy(std::string s) {
ltrim(s);
return s;
}

// trim from end (copying)
static inline std::string rtrim_copy(std::string s) {
rtrim(s);
return s;
}

// trim from both ends (copying)
static inline std::string trim_copy(std::string s) {
trim(s);
return s;
}

boost提供的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <boost/algorithm/string.hpp>

string str1=" hello world! ";
string str2=trim_left_copy(str1); // str2 == "hello world! "
string str3=trim_right_copy(str1); // str3 == " hello world!"
trim(str1); // str1 == "hello world!"

string phone="00423333444";
// remove leading 0 from the phone number
trim_left_if(phone,is_any_of("0")); // phone == "423333444"


std::string str("hello world! ");
boost::trim_right(str);
boost::trim_left(str);
boost::trim(str);