【问题标题】:Removing Non-printable Unicode characters from a TChar*从 TChar* 中删除不可打印的 Unicode 字符
【发布时间】:2024-01-18 08:43:01
【问题描述】:

我有一个tchar* 和字符串The system time has changed to ‎2018‎ - ‎09‎ - ‎06T15:13 : 52.257364700Z from ‎2018‎ - ‎09‎ - ‎06T15 : 13 : 52.257364700Z.

当我输入该字符串 here 时,我会在我的日期值周围看到字符,当我使用 wPrintf 打印它时,我会在这些位置得到问号。

有没有办法遍历 tchar* 并删除非 ASCII 字符?

int main() {
    const TCHAR *pText = _T("The system time has changed to ‎2018‎ - ‎09‎ - ‎06T15:13 : 52.257364700Z from ‎2018‎ - ‎09‎ - ‎06T15 : 13 : 52.257364700Z.");
    TCHAR* temp;
    temp = removet((TCHAR*)pText, _tcslen(pText)); 

    wprintf(_T("%s"), temp);
}

TCHAR* removet(TCHAR* text, int len) {
    int offset = 0;
    for (int i = 0; text[i] != 0; ++i) {

        if (text[i] > 127) {
            offset++;
        }
        if (!((i + offset) > len)) {
            wprintf(_T("%d"), i +offset);
            text[i] = text[i + offset];
        }
   }
   return text;
}

更正的代码:

int main() {
    const TCHAR *pText = _T("The system time has changed to ‎2018‎ - ‎09‎ - ‎06T15:13 : 52.257364700Z from ‎2018‎ - ‎09‎ - ‎06T15 : 13 : 52.257364700Z.");
    TCHAR* temp;
    temp = removet((TCHAR*)pText, _tcslen(pText)); 

    wprintf(_T("%s"), temp);
}

TCHAR* removet(TCHAR* text, int len) {
    int offset = 0; 
    TCHAR* str2 = new TCHAR[len+1];
    _tcscpy_s(str2, len+1, text);
    for (int i = 0; str2[i] != 0; ++i) {

        if (str2[i+offset] > 127) {
            offset++;
        }
        if (!((i + offset) >= len)) {
           str2[i] = str2[i + offset];
        }
    }
    return str2;
}

【问题讨论】:

  • 请记住纯 ASCII 是一个 位字符集。如果字符串以 UTF-8 编码(向后兼容 ASCII),则“特殊”字符应设置其高(八)位。
  • @Someprogrammerdude 对tcharwPrintf 的引用表明它是UTF-16,这将使这个问题变得微不足道。只需删除 1-127 范围之外的每个字符。
  • 当我尝试遍历 tchar* 时出现异常,但如何遍历 tchar? @MarkRansom
  • 您没有显示任何代码,因此无法看到您做错了什么。你知道当你找到一个零值的字符时你应该停止迭代,对吧?
  • 你的问题是当i增加到最大值时,i+offset会越界。我看到你检查了,但你需要使用 >= 而不是 >

标签: c++ unicode tchar


【解决方案1】:

如果您使用 std::string 而不是原始字符数组,这会更容易,但您仍然可以使用一些 c++ 功能:

#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>

int main()
{
    tchar* test = new tchar[100];
    _tcscpy(test, _T("test string 1235"));
    tchar* end = std::remove_if(test, test + _tcslen(test), [](tchar ch){ return ch >= 127;} );
    *end = '\0';
    std::cout << test << "\n";
}

并使用std::basic_string

#include <iostream>
#include <string>
#include <algorithm>

int main()
{
    std::basic_string<tchar> test = _T("test string 1235");
    auto end = std::remove_if(test.begin(), test.end(), [](tchar ch){ return ch >= 127;} );
    test.erase(end, test.end());
    std::cout << test << "\n";
}

【讨论】:

    最近更新 更多