Annotation of nono/lib/mystring.cpp, revision 1.1.1.5

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #include "mystring.h"
1.1.1.2   root        8: #include <algorithm>
1.1       root        9: 
                     10: std::string
                     11: string_format(const char *fmt, ...)
                     12: {
                     13:        va_list ap;
                     14:        char *buf;
                     15: 
                     16:        va_start(ap, fmt);
                     17:        vasprintf(&buf, fmt, ap);
                     18:        va_end(ap);
                     19:        std::string rv(buf);
                     20:        free(buf);
                     21: 
                     22:        return rv;
                     23: }
                     24: 
1.1.1.2   root       25: // 文字列 str から先頭の連続する空白文字を取り除いた新しい文字列を返す。
                     26: std::string
                     27: string_ltrim(const std::string& str)
                     28: {
                     29:        auto it = str.begin();
                     30:        for (; it != str.end(); it++) {
                     31:                if (!isspace(*it))
                     32:                        break;
                     33:        }
                     34:        return std::string(it, str.end());
                     35: }
                     36: 
                     37: // 文字列 str から末尾の連続する空白文字を取り除く (str を書き換える)。
                     38: void
                     39: string_rtrim(std::string& str)
                     40: {
                     41:        while (isspace(*str.rbegin())) {
                     42:                str.pop_back();
                     43:        }
                     44: }
                     45: 
                     46: // 文字列 str から末尾の連続する空白文字を取り除く (str を書き換える)。
                     47: void
                     48: rtrim(char *str)
                     49: {
                     50:        char *p = strchr(str, '\0');
1.1.1.5 ! root       51:        while (--p >= str && isspace((int)*p)) {
1.1.1.2   root       52:                *p = '\0';
                     53:        }
                     54: }
                     55: 
1.1.1.5 ! root       56: // 文字列 str から先頭と末尾の連続する空白文字を取り除いた新しい文字列を返す。
        !            57: std::string
        !            58: string_trim(const std::string& str)
        !            59: {
        !            60:        int s = 0;
        !            61:        int e = str.size();
        !            62: 
        !            63:        for (; s < e; s++) {
        !            64:                if (!isspace(str[s]))
        !            65:                        break;
        !            66:        }
        !            67:        for (e--; e >= s; e--) {
        !            68:                if (!isspace(str[e]))
        !            69:                        break;
        !            70:        }
        !            71: 
        !            72:        return str.substr(s, e - s + 1);
        !            73: }
        !            74: 
1.1.1.2   root       75: // 文字列 src 中の ASCII 大文字を小文字にした新しい文字列を返す。
                     76: std::string
                     77: string_tolower(const std::string& src)
                     78: {
                     79:        std::string dst(src);
                     80:        std::transform(dst.begin(), dst.end(), dst.begin(),
                     81:                [](unsigned char c){ return std::tolower(c); });
                     82:        return dst;
                     83: }
                     84: 
1.1.1.4   root       85: // 文字列 lhs の先頭が rhs と大文字小文字の区別なしで一致すれば true を返す。
                     86: // ASCII 専用。
                     87: // C++20 の starts_with に似せておく。
                     88: bool
                     89: starts_with_ignorecase(const std::string& lhs, const std::string& rhs)
                     90: {
                     91:        if (lhs.length() < rhs.length()) {
                     92:                return false;
                     93:        }
                     94: #if 0
                     95:        return std::equal(
                     96:                lhs.begin(), lhs.begin() + rhs.length(),
                     97:                rhs.begin(),
                     98:                [](std::string::value_type l, std::string::value_type r) {
                     99:                        return std::tolower(l) == std::tolower(r);
                    100:                }
                    101:        );
                    102: #else
                    103:        // こっちのほうが分かりやすいよな
                    104:        return strncasecmp(lhs.c_str(), rhs.c_str(), rhs.length()) == 0;
                    105: #endif
                    106: }
                    107: 
                    108: // 文字列 str (長さ len) を文字 c で分割したリストを返す。
                    109: std::vector<std::string>
1.1.1.5 ! root      110: string_split(const char *str, int len, char c, int nlimit)
1.1.1.4   root      111: {
                    112:        std::vector<std::string> list;
                    113: 
1.1.1.5 ! root      114:        // 空文字列なら空リスト
        !           115:        if (len == 0) {
        !           116:                return list;
        !           117:        }
        !           118: 
        !           119:        int pos = 0;
        !           120:        int end = 0;
        !           121: 
        !           122:        for (; ; pos = end + 1) {
        !           123:                // 上限に達するならこれ以降は一要素として返す
        !           124:                if (nlimit > 0 && list.size() >= nlimit - 1) {
        !           125:                        list.emplace_back(str + pos, len - pos);
        !           126:                        break;
        !           127:                }
        !           128: 
1.1.1.4   root      129:                const char *p = strchr(str + pos, c);
                    130:                if (p) {
                    131:                        end = p - str;
                    132:                } else {
                    133:                        end = len;
                    134:                }
                    135: 
                    136:                list.emplace_back(str + pos, end - pos);
1.1.1.5 ! root      137:                if (p == NULL)
        !           138:                        break;
1.1.1.4   root      139:        }
                    140: 
                    141:        return list;
                    142: }
                    143: 
1.1       root      144: #if 0
                    145: #include <cstdio>
                    146: #include <sys/time.h>
                    147: int main()
                    148: {
                    149:        std::string s0 = string_format("%d_%d", 0, 1);
                    150:        if (s0 != "0_1") {
                    151:                printf("error\n");
                    152:                return 1;
                    153:        }
                    154:        timeval start, end, result;
                    155:        gettimeofday(&start, NULL);
                    156:        for (int i = 0; i < 100000; i++) {
                    157:                std::string s = string_format("%d_%d", i, i);
                    158:        }
                    159:        gettimeofday(&end, NULL);
                    160:        timersub(&end, &start, &result);
                    161:        long long t = (result.tv_sec) * 1000000 + result.tv_usec;
                    162:        printf("%d.%03d\n", (int)t / 1000, (int)t % 1000);
                    163:        return 0;
                    164: }
                    165: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.