【问题标题】:How to find out if there is any non ASCII character in a string with a file path如何找出具有文件路径的字符串中是否有任何非ASCII字符
【发布时间】:2018-06-21 03:11:07
【问题描述】:

检测文件路径中是否有非ASCII字符

我有一个 UTF-8 编码的 Unicode 字符串,用于存储文件路径,例如 C:\Users\myUser\Downloads\ü.pdf。我已经检查过该字符串在本地文件系统中是否包含正确的文件路径,但是由于我将此字符串发送到仅支持 ASCII 的不同进程,因此我需要确定该字符串是否包含任何非 ASCII 字符。

我该怎么做?

【问题讨论】:

  • 转换为 ASCII,转换回 UTF-8,然后将原始字符串与已转换两次的字符串进行比较。如果比较成功,则发送 ASCII 字符串。

标签: c++ string unicode utf-8 ascii


【解决方案1】:

ASCII 字符仅使用 char 的低 7 位(值 0-127)。以 UTF-8 编码的非 ASCII Unicode 字符使用所有设置了高位的 char 元素。因此,您可以简单地迭代 char 元素,看看它们中的任何一个的值是否高于 127,例如:

bool containsOnlyASCII(const std::string& filePath) {
  for (auto c: filePath) {
    if (static_cast<unsigned char>(c) > 127) {
      return false;
    }
  }
  return true;
}

关于演员表的注释:std::string 包含 char 元素。该标准没有定义charsigned 还是unsigned。如果它是signed,那么我们可以以明确定义的方式将其转换为unsigned。该标准明确规定了这是如何完成的。

【讨论】:

    【解决方案2】:

    根据几个 cmets 的建议并由 @CrisLuengo 回答突出显示,我们可以迭代字符以查找高位集合 (live example) 中的任何字符:

    #include <iostream>
    #include <string>
    #include <algorithm>
    
    bool isASCII (const std::string& s)
    {
        return !std::any_of(s.begin(), s.end(), [](char c) { 
            return static_cast<unsigned char>(c) > 127; 
        });
    }
    
    int main()
    {
        std::string s1 { "C:\\Users\\myUser\\Downloads\\Hello my friend.pdf" };   
        std::string s2 { "C:\\Users\\myUser\\Downloads\\ü.pdf" };
    
        std::cout << std::boolalpha << isASCII(s1) << "\n";
        std::cout << std::boolalpha << isASCII(s2) << "\n";
    }
    

    是的

    【讨论】:

    • 尽管这可能不是解决方案,但该功能可以缩短为 return std::all_of(filepath.begin(), filepath.end(), ::isprint);
    • @1201ProgramAlarm stackoverflow.com/questions/21805674/… 强制转换是为了避免由于负值导致的未定义行为,尽管在这种特殊情况下永远不会发生
    • @PaulMcKenzie 你是对的,那会更短,但为什么这可能不是解决方案?举个反例会很有帮助。
    • 请注意isprint 的行为取决于当前的 C 语言环境。如果有人更改了语言环境,这将不再检查“可打印的 ASCII”。至少,我会更改函数的名称以避免混淆。
    • 我可能会使用 bool isASCII = std::all_of(filepath.begin(), filepath.end(), [](char c){ return static_cast&lt;unsigned char&gt;(c) &lt;= 127; });bool isASCII = !std::any_of(filepath.begin(), filepath.end(), [](char c){ return static_cast&lt;unsigned char&gt;(c) &gt; 127; }); 之类的东西
    猜你喜欢
    • 1970-01-01
    • 2012-11-11
    • 1970-01-01
    • 1970-01-01
    • 2014-12-05
    • 2013-09-08
    • 2018-12-25
    • 2015-02-19
    • 1970-01-01
    相关资源
    最近更新 更多