您如何处理标准库的signed char -> int 问题?

2024-04-22

这是我工作中一个长期存在的问题,我意识到我still没有好的解决办法...

C 天真地为 int 定义了它的所有字符测试函数:

int isspace(int ch);

但是字符通常是带符号的,并且完整的字符通常不适合 int 或用于字符串的任何单个存储单元*****。

这些函数已成为当前 C++ 函数和方法的逻辑模板,并为当前标准库奠定了基础。事实上,他们仍然受到支持。

因此,如果您传递 isspace(*pchar) ,您最终可能会遇到符号扩展问题。它们很难被发现,因此根据我的经验,它们很难防范。

类似地,因为 isspace() 及其同类都采用整数,并且因为字符的实际宽度通常在没有字符串分析的情况下是未知的 - 这意味着任何现代字符库本质上都不应该围绕 char 或 wchar_t 而只围绕指针/迭代器,因为只有通过分析字符流才能知道它有多少组成单个逻辑字符,所以我对如何最好地解决这些问题感到有点茫然?

我一直期待一个真正强大的库,基于抽象出任何字符的大小因素,并且仅使用字符串(提供 isspace 等),但要么我错过了它,要么有另一个更简单的解决方案在等着我面对你们所有人(知道自己在做什么的人)都使用...


** 对于可以完全包含完整字符的固定大小的字符编码,这些问题不会出现 - UTF-32 显然是具有这些特征的唯一选项(或将自身限制为 ASCII 或某些此类的特殊环境) 。


所以,我的问题是:

“如何以一种不会遇到两个问题的方式测试空白、可打印等:

1) 符号扩展,以及
2)变宽字符问题

毕竟,大多数字符编码是可变宽度的:UTF-7、UTF-8、UTF-16 以及旧标准(例如 Shift-JIS)。如果编译器将 char 视为带符号的 8 位单元,那么即使是扩展的 ASCII 也可能存在简单的符号扩展问题。

请注意:

无论你的 char_type 大小是多少,对于大多数字符编码方案来说都是错误的。

这个问题在标准C库中,以及在C++标准库中;它仍然尝试在各种 isspace、isprint 等实现中传递 char 和 wchar_t,而不是字符串迭代器。

实际上,正是这些类型的函数破坏了 std::string 的通用性。如果它只在存储单元中工作,并且不试图假装将存储单元的含义理解为逻辑字符(例如 isspace),那么抽象就会更加诚实,并且会迫使我们程序员去寻找其他地方寻找有效的解决方案...

谢谢

所有参与的人。在这次讨论和WChars、编码、标准和可移植性 https://stackoverflow.com/questions/6300804/wchars-encodings-standards-and-portability我对这些问题有了更好的处理。尽管没有简单的答案,但一点点理解都会有所帮助。


如何以不受两个问题困扰的方式测试空白、可打印等:
1)符号扩展
2)变宽字符问题
毕竟,无论程序员是否意识到,所有常用的 Unicode 编码都是可变宽度的:UTF-7、UTF-8、UTF-16,以及 Shift-JIS 等较旧的标准...

显然,您必须使用支持 Unicode 的库,因为您已经(正确地)证明了 C++03 标准库不是。 C++11 库得到了改进,但对于大多数用途来说仍然不够好。是的,某些操作系统具有 32 位 wchar_t,这使它们能够正确处理 UTF32,但这只是一种实现,并不能由 C++ 保证,并且对于许多 unicode 任务来说远远不够,例如迭代字形(字母) 。

IBMICU http://www-306.ibm.com/software/globalization/icu/index.jsp
Libiconv http://www.gnu.org/software/libiconv/
微UTF-8 http://puszcza.gnu.org.ua/software/microutf8/
UTF-8 CPP,版本 1.0 https://sourceforge.net/projects/utfcpp
utfproc http://www.flexiguided.de/publications.utf8proc.en.html
还有更多在http://unicode.org/resources/libraries.html http://unicode.org/resources/libraries.html.

如果问题不是关于特定字符测试,而是更多关于一般代码实践:请执行您的框架所做的任何事情。如果您正在为 linux/QT/networking 编码,请将所有内容保留在内部 UTF-8 中。如果您使用 Windows 进行编码,请将所有内容在内部保存为 UTF-16。如果您需要弄乱代码点,请将所有内容保留在内部 UTF-32 中。否则(对于可移植的通用代码),做任何你想做的事,因为无论如何,你都必须针对某些操作系统或其他操作系统进行翻译。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

您如何处理标准库的signed char -> int 问题? 的相关文章

  • 如何使 Windows 窗体的关闭按钮不关闭窗体但使其不可见?

    该表单有一个 NotifyIcon 对象 当用户单击 关闭 按钮时 我希望表单不关闭而是变得不可见 然后 如果用户想再次查看该表单 可以双击系统托盘中的图标 如果用户想关闭表单 可以右键单击该图标并选择 关闭 有人可以告诉我如何使关闭按钮不
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • 如何返回 json 结果并将 unicode 字符转义为 \u1234

    我正在实现一个返回 json 结果的方法 例如 public JsonResult MethodName Guid key var result ApiHelper GetData key Data is stored in db as v
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 如何将单个 char 转换为 int [重复]

    这个问题在这里已经有答案了 我有一串数字 例如 123456789 我需要提取它们中的每一个以在计算中使用它们 我当然可以通过索引访问每个字符 但是如何将其转换为 int 我研究过 atoi 但它需要一个字符串作为参数 因此 我必须将每个字
  • C++ 复制初始化和直接初始化,奇怪的情况

    在继续阅读本文之前 请阅读在 C 中 复制初始化和直接初始化之间有区别吗 https stackoverflow com questions 1051379 is there a difference in c between copy i
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • 如何让Gtk+窗口背景透明?

    我想让 Gtk 窗口的背景透明 以便只有窗口中的小部件可见 我找到了一些教程 http mikehearn wordpress com 2006 03 26 gtk windows with alpha channels https web
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • 如何在 C++ BOOST 中像图形一样加载 TIFF 图像

    我想要加载一个 tiff 图像 带有带有浮点值的像素的 GEOTIFF 例如 boost C 中的图形 我是 C 的新手 我的目标是使用从源 A 到目标 B 的双向 Dijkstra 来获得更高的性能 Boost GIL load tiif
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐