提问人:Michal Hadraba 提问时间:11/2/2023 最后编辑:Remy LebeauMichal Hadraba 更新时间:11/2/2023 访问量:91
如何在 c++ 中比较 char(或 wchar_t)作为字符串的一部分
How compare char (or wchar_t) as part of string in c++
问:
我有两个 C 风格的以空结尾(宽)字符串(不是 std::wstring
),我通过迭代器浏览它们,并想逐个字符比较它们(用于排序)。我不需要使用标准运算符(,,),因为我想通过本地规则(设置_locale_t)来比较它们。==
>
<
我只找到了 ,它可以比较两个字符串,而不是字符。_wcsicmp_l(wchar_t*, wchar_t*, _locale_t)
当我将指向比较函数上的参数的指针传递时,就像字符串的一部分(字符串的迭代器)一样,该函数会像指向字符串的指针一样获取它,并且正在比较两个完整的字符串,而不仅仅是字符。wchar_t
我认为一个例子会更能说明问题。这是一个好方法,还是太难太慢?有没有办法更容易做到?
目标提供自然排序 - 字符串包括字符和数字。
inline bool compareChars(const wchar_t& lhs, const wchar_t& rhs)
{
//I have to add terminate \0 here, in otherwise comparator compare string from lhs to end, not only chars
wchar_t str_lhs[2]{ lhs, L'\0' }, str_rhs[2]{ rhs, L'\0' };
_locale_t loc = _create_locale(LC_ALL, "cs-CZ.utf8");
bool res = _wcsicoll_l(&str_lhs[0], &str_rhs[0], loc) < 0;
_free_locale(loc);
return res;
}
int main()
{
const wchar_t* firstStr = L"Test", * secondStr = L"Test2";
const wchar_t* it1 = firstStr;
const wchar_t* it2 = secondStr;
const wchar_t* itEnd1 = it1;
while (*itEnd1 != '\0')itEnd1++;
const wchar_t* itEnd2 = it2;
while (*itEnd2 != '\0')itEnd2++;
for (; it1 != itEnd1; ++it1) //Go througth first string
for (; it2 != itEnd2; ++it2) //Go througth second string
{
int res = compareChars(*it1, *it2); //chars like a part of string
}
return 0;
}
答:
0赞
Michal Hadraba
11/2/2023
#1
结果在这里:
#include <locale>
#include <string>
using namespace std;
namespace MajCompare {
struct MajLoc
{
private:
_locale_t m_loc;
public:
MajLoc(){ m_loc = _create_locale(LC_COLLATE, "cs-CZ.utf8"); }
~MajLoc() { _free_locale(m_loc);}
_locale_t& GetLocale() { return m_loc; }
};
static MajLoc s_cLoc;
//Vrací -1, 0 1
int CompareNatural(const wchar_t* lhsBegin, const wchar_t* lhsEnd
, const wchar_t* rhsBegin, const wchar_t* rhsEnd)
{
wstring wsPom1, wsPom2;
const wchar_t* itCurLhs = lhsBegin, *itCurRhs = rhsBegin;
while (!iswdigit(*itCurLhs) && !iswdigit(*itCurRhs) && itCurLhs != lhsEnd && itCurRhs != rhsEnd)
{
wsPom1.push_back(*itCurLhs);
wsPom2.push_back(*itCurRhs);
if (*itCurLhs != *itCurRhs)
return _wcsicoll_l(lhsBegin, rhsBegin, s_cLoc.GetLocale());
itCurLhs++, itCurRhs++;
}
if (itCurLhs == lhsEnd || itCurRhs == rhsEnd || iswdigit(*itCurLhs) != iswdigit(*itCurRhs)) //jeden je delší nebo kombinace čísla a písmena, porovnáme původní řetězce bez ohledu na čísla porovnáme standardně
return _wcsicoll_l(lhsBegin, rhsBegin, s_cLoc.GetLocale());
else //oba řetězce mají čísla a nejsou na konci
{
wstring wsNum1, wsNum2;
while (iswdigit(*itCurLhs))
wsNum1.push_back(*itCurLhs++);
while (iswdigit(*itCurRhs))
wsNum2.push_back(*itCurRhs++);
int iNum1 = _wtoi(wsNum1.data());
int iNum2 = _wtoi(wsNum2.data());
if (iNum1 != iNum2)
return iNum1 > iNum2 ? 1 : -1;
return CompareNatural(itCurLhs, lhsEnd, itCurRhs, rhsEnd);
}
}
int CompareNatural(const wchar_t* lsFirst, const wchar_t* lsSecond)
{
const wchar_t* it1 = lsFirst;
while (*it1 != '\0')it1++;
const wchar_t* it2 = lsSecond;
while (*it2 != '\0')it2++;
return CompareNatural(lsFirst, it1, lsSecond, it2);
}
};
评论
ch
c
d