--- nono/lib/mystring.cpp 2026/04/29 17:04:28 1.1 +++ nono/lib/mystring.cpp 2026/04/29 17:04:57 1.1.1.5 @@ -1,10 +1,11 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // -#include "header.h" #include "mystring.h" +#include std::string string_format(const char *fmt, ...) @@ -21,6 +22,125 @@ string_format(const char *fmt, ...) return rv; } +// 文字列 str から先頭の連続する空白文字を取り除いた新しい文字列を返す。 +std::string +string_ltrim(const std::string& str) +{ + auto it = str.begin(); + for (; it != str.end(); it++) { + if (!isspace(*it)) + break; + } + return std::string(it, str.end()); +} + +// 文字列 str から末尾の連続する空白文字を取り除く (str を書き換える)。 +void +string_rtrim(std::string& str) +{ + while (isspace(*str.rbegin())) { + str.pop_back(); + } +} + +// 文字列 str から末尾の連続する空白文字を取り除く (str を書き換える)。 +void +rtrim(char *str) +{ + char *p = strchr(str, '\0'); + while (--p >= str && isspace((int)*p)) { + *p = '\0'; + } +} + +// 文字列 str から先頭と末尾の連続する空白文字を取り除いた新しい文字列を返す。 +std::string +string_trim(const std::string& str) +{ + int s = 0; + int e = str.size(); + + for (; s < e; s++) { + if (!isspace(str[s])) + break; + } + for (e--; e >= s; e--) { + if (!isspace(str[e])) + break; + } + + return str.substr(s, e - s + 1); +} + +// 文字列 src 中の ASCII 大文字を小文字にした新しい文字列を返す。 +std::string +string_tolower(const std::string& src) +{ + std::string dst(src); + std::transform(dst.begin(), dst.end(), dst.begin(), + [](unsigned char c){ return std::tolower(c); }); + return dst; +} + +// 文字列 lhs の先頭が rhs と大文字小文字の区別なしで一致すれば true を返す。 +// ASCII 専用。 +// C++20 の starts_with に似せておく。 +bool +starts_with_ignorecase(const std::string& lhs, const std::string& rhs) +{ + if (lhs.length() < rhs.length()) { + return false; + } +#if 0 + return std::equal( + lhs.begin(), lhs.begin() + rhs.length(), + rhs.begin(), + [](std::string::value_type l, std::string::value_type r) { + return std::tolower(l) == std::tolower(r); + } + ); +#else + // こっちのほうが分かりやすいよな + return strncasecmp(lhs.c_str(), rhs.c_str(), rhs.length()) == 0; +#endif +} + +// 文字列 str (長さ len) を文字 c で分割したリストを返す。 +std::vector +string_split(const char *str, int len, char c, int nlimit) +{ + std::vector list; + + // 空文字列なら空リスト + if (len == 0) { + return list; + } + + int pos = 0; + int end = 0; + + for (; ; pos = end + 1) { + // 上限に達するならこれ以降は一要素として返す + if (nlimit > 0 && list.size() >= nlimit - 1) { + list.emplace_back(str + pos, len - pos); + break; + } + + const char *p = strchr(str + pos, c); + if (p) { + end = p - str; + } else { + end = len; + } + + list.emplace_back(str + pos, end - pos); + if (p == NULL) + break; + } + + return list; +} + #if 0 #include #include