`strtoul()` 对于非常“负”的字符串,正确的返回值是什么?

2023-12-02

这是一提出并回答自己的问题是可以的。 我研究了这个问题,发现结果很奇怪,并发布了我的发现。


“非常负”的字符串应该返回什么值strtoul(): 1, ULONG_MAX或者是什么?


strtol()

对于表示数值的字符串,例如"123", strtol()行为符合预期。琴弦(蓝色)[LONG_MIN ... LONG_MAX]转换成他们的预期long价值。上面的绳子(黄色)LONG_MAX转换成LONG_MAX并设置errno==ERANGE。下面的字符串LONG_MIN转换成LONG_MIN并设置errno==ERANGE.

strtoul()积极的

对于表示数值的字符串,例如"123", strtoul()也按预期运行。弦(红)[0 ... ULONG_MAX]转换成他们的预期unsigned long价值。上面的字符串(绿色)ULONG_MAX转换成ULONG_MAX并设置errno==ERANGE.

如果主题序列以减号开头,则转换产生的值将被取反(在返回类型中)。 C17dr § 7.22.1.4 5

strtoul()消极的

对于字符串(红色)[-ULONG_MAX ... -1],转换否定正转换并添加ULONG_MAX + 1(就像典型的将负值分配给unsigned)并且不设置errno。这有点令人惊讶,但这就是规范的定义方式。

strtoul()非常消极 - 问题

对于字符串(绿色)小于-ULONG_MAX,我希望转换像上述较小的负值一样处理:转换否定正转换(ULONG_MAX由于溢出)并添加ULONG_MAX + 1。预期结果1(或者可能0) with errno == ERANGE。还在锻炼strtoul()导致ULONG_MAX.

什么是正确的?

strtoul

测试代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

long strtol_test(const char *s, int base) {
  printf("\n");
  int width = snprintf(NULL, 0, "%ld", LONG_MIN);
  printf("base:%2d \"%s\"\n", base, s);

  char *endptr_signed;
  errno = 0;
  long val_signed = strtol(s, &endptr_signed, base);
  int errno_signed = errno;

  char *endptr_unsigned;
  errno = 0;
  unsigned long val_unsigned = strtoul(s, &endptr_unsigned, base);
  int errno_unsigned = errno;

  if (val_signed < 0 || (unsigned long) val_signed != val_unsigned
      || endptr_signed != endptr_unsigned || errno_signed != errno_unsigned) {
    printf("  signed  val:%*ld end:%2td e:%s\n", width, val_signed,
        endptr_signed - s, strerror(errno_signed));
    printf("unsigned  val:%*lu end:%2td e:%s\n", width, val_unsigned,
        endptr_unsigned - s, strerror(errno_unsigned));
    return 1;
  }

  printf("    both  val:%*ld end:%2td e:%s\n", width, val_signed,
      endptr_signed - s, strerror(errno_signed));
  return 0;
}

int main() {
  char s[][50] = {"-ULONG_MAX1", "-ULONG_MAX", "LONG_MIN1", "LONG_MIN", "-1",
      "-0", "42", "LONG_MAX", "LONG_MAX1", "ULONG_MAX", "ULONG_MAX1", "x"};
  snprintf(s[0], sizeof *s, "-%lu", ULONG_MAX);
  s[0][strlen(s[0]) - 1]++;
  snprintf(s[1], sizeof *s, "-%lu", ULONG_MAX);
  snprintf(s[2], sizeof *s, "%ld", LONG_MIN);
  s[2][strlen(s[2]) - 1]++;
  snprintf(s[3], sizeof *s, "%ld", LONG_MIN);

  snprintf(s[7], sizeof *s, "%ld", LONG_MAX);
  snprintf(s[8], sizeof *s, "%ld", LONG_MAX);
  s[8][strlen(s[8]) - 1]++;
  snprintf(s[9], sizeof *s, "%lu", ULONG_MAX);
  snprintf(s[10], sizeof *s, "%lu", ULONG_MAX);
  s[10][strlen(s[10]) - 1]++;

  strcpy(s[11], s[0]);
  s[11][strlen(s[11]) - 1]++;

  int n = sizeof s / sizeof s[0];
  for (int i = 0; i < n; i++) {
    strtol_test(s[i], 0);
  }
}

样本输出

base: 0 "-18446744073709551616"
  signed  val:-9223372036854775808 end:21 e:Numerical result out of range
unsigned  val:18446744073709551615 end:21 e:Numerical result out of range

base: 0 "-18446744073709551615"
  signed  val:-9223372036854775808 end:21 e:Numerical result out of range
unsigned  val:                   1 end:21 e:No error

base: 0 "-9223372036854775809"
  signed  val:-9223372036854775808 end:20 e:Numerical result out of range
unsigned  val: 9223372036854775807 end:20 e:No error

base: 0 "-9223372036854775808"
  signed  val:-9223372036854775808 end:20 e:No error
unsigned  val: 9223372036854775808 end:20 e:No error

base: 0 "-1"
  signed  val:                  -1 end: 2 e:No error
unsigned  val:18446744073709551615 end: 2 e:No error

base: 0 "-0"
    both  val:                   0 end: 2 e:No error

base: 0 "42"
    both  val:                  42 end: 2 e:No error

base: 0 "9223372036854775807"
    both  val: 9223372036854775807 end:19 e:No error

base: 0 "9223372036854775808"
  signed  val: 9223372036854775807 end:19 e:Numerical result out of range
unsigned  val: 9223372036854775808 end:19 e:No error

base: 0 "18446744073709551615"
  signed  val: 9223372036854775807 end:20 e:Numerical result out of range
unsigned  val:18446744073709551615 end:20 e:No error

base: 0 "18446744073709551616"
  signed  val: 9223372036854775807 end:20 e:Numerical result out of range
unsigned  val:18446744073709551615 end:20 e:Numerical result out of range

base: 0 "-18446744073709551617"
  signed  val:-9223372036854775808 end:21 e:Numerical result out of range
unsigned  val:18446744073709551615 end:21 e:Numerical result out of range

范围错误结果始终是ULONG_MAX for strtoul().

对于像这样的字符串来说,这相当简单"-18446744073709551616",由于正确(正)值超出范围,ULONG_MAX被返回并且errno被设定为ERANGE。没有关于范围误差的规定strtoul()提供任何其他答案。

...如果正确值超出了可表示值的范围,...ULONG_MAX, ... 返回(根据值的返回类型和符号,如果有),以及宏的值ERANGE存储在errno。 C17dr § 7.22.1.4 8

Thus strtoul()当字符串位于[-ULONG_MAX ... +ULONG_MAX]范围。转换后的结果是unsigned long [0 ... ULONG_MAX]。错误结果总是ULONG_MAX.

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

`strtoul()` 对于非常“负”的字符串,正确的返回值是什么? 的相关文章

  • 根据当前文化调用不同(本地化)视图

    我在用着LocalizationAttribute它实现了ActionFilterAttribute本地化视图 我简单地说 Localize 在控制器上 我使用 LocalizeStrings resx 文件根据当前线程上的语言进行应用 一
  • 获取当前用户的 NetworkCredential (C#)

    我正在尝试从控制台应用程序调用 Web 服务 并且我需要向客户端提供System Net NetworkCredential object 是否有可能创建一个NetworkCredential启动应用程序的用户的对象而不提示输入用户名 密码
  • 在宏中使用 # [重复]

    这个问题在这里已经有答案了 请解释一下代码 include
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • C# Visual Studio 动态代码片段

    我正在开发一个 WinForms 项目 每天都会执行一些重复性的任务 所以我认为创建代码片段 https msdn microsoft com en us library ms165394 v vs 110 aspx会帮助我 但它仅适用于固
  • 在 C/C++ 中绘制填充椭圆的简单算法

    在SO上 找到了以下绘制实心圆的简单算法 for int y radius y lt radius y for int x radius x lt radius x if x x y y lt radius radius setpixel
  • VS2010中VSHost.exe不断启动

    我正在 VS2010 中使用一个包含大量项目的解决方案 但它不断变得无响应 我注意到的一件事可能是一条线索 尽管我尚未开始任何调试 但 MyApplicationName vshost exe 不断出现在进程列表中 也许每当构建发生时它就会
  • 如何将 QSerialPort 模块添加到 CMake 中?

    我想将 QSerialPort 模块添加到 CMake 中 根据我的理解 我需要将QT 串口添加到 pro中 我只想使用 CMake 所以我尝试编译简单的 CMake 文件 但有错误 QtCore 正在工作 qDebug 可以毫无问题地显示
  • 命令中带空格的 Windows C 系统调用

    我无法使用名称和参数中的空格进行系统调用 例如 system c program files something example exe c my files example txt 我尝试过各种我知道的方法来逃避 但没有任何效果 我努力了
  • 用于 C/C++ 的独立跨平台 (Windows/Linux) 文件压缩?

    我正在寻找一个 最好是小的 C 或 C 开源库 我可以将其包含在我的 MIT 许可项目中 托管在 google 代码上 我是一名业余爱好 C C 程序员 所以我并不那么先进 但我只知道为名为 SA MP 的应用程序 适用于 Windows
  • 如果 .txt 文件不存在,则创建一个,如果存在则追加新行

    我想创建一个 txt 文件并写入它 如果该文件已经存在 我只想添加更多行 string path E AppServ Example txt if File Exists path File Create path TextWriter t
  • 第三方引用的 dll 未被复制来构建

    我有一个第三方 net dll 被我的 dll 类库项目 A 引用和使用 我的控制台应用程序项目 B 引用项目 A 我的问题是第三方 dll 没有被复制到控制台应用程序项目 B 的构建中 这里有什么问题呢 我的 dll 类库中引用的第三方
  • 除法时的小数舍入误差 (C#)

    我基本上有四个数字 比如 100 200 300 400 我需要计算概率为 100 100 200 300 400 200 100 200 300 400 等等在 当我使用小数数据类型来存储这些概率时 由于舍入问题 它们不会达到 1 在不使
  • 实体框架中的导航属性是什么

    我是实体框架的新手 当Visual Studio创建模型图时我们主要可以看到Entities Propertie和Navigation Properties这两个东西 那么这些Navigation Properties是什么 如何使用它们
  • 没有类型的 IEnumerable 属性

    我正在尝试创建一个类似于来自 MSDN 的官方 DataGrid ItemsSource 的属性 public IEnumerable ItemsSource get set 这提供了对任何派生类中任何类型的支持 有了这个 我可以设置类似的
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • Task.Delay 到底是如何工作的?

    他们说 Task Delay 是一个异步 Thread Sleep 为了测试这一点 我写了下面的代码 我希望立即打印 One 然后 3 秒后将打印结果变量 15 2 秒后 将打印 Two 但似乎并非如此 一 不会立即打印 3 秒后打印 On
  • 如何从与 C# lambda 集成(而非代理集成)的 Amazon API 网关获取正确的 http 状态代码?

    我正在使用 C lambda 与 API 网关集成 我希望 API 网关返回正确的错误代码 例如 400 404 500 等 API网关模块tf文件 provider aws version lt 2 70 0 region var aws
  • 有关 Endian 性和 .Net 的详细信息?

    我有几个关于字节顺序的问题 这些问题足够相关 我保证将它们作为一个问题提出 1 字节顺序是由 Net还是由硬件决定的 2 如果是由硬件决定的 我怎样才能在C 中找出硬件的字节序 3 字节序是否影响二进制交互 例如 OR AND OR 或移位

随机推荐

  • R.java 文件未创建

    我的 Android 应用程序中有 R java 文件 但我不知道 它是如何删除的 要再次创建它 我清理我的项目 并通过单击 构建项目 重建我的项目 我不知道是什么问题 它不会再次被创建 一般来说 每当我构建项目时它都会自动创建 如果您在更
  • firebase获取每个子项的子项的数据

    大家好 我是 firebase 的超级新手 我需要一些帮助 首先 我正在做的是一份清单 例如 刻度表包含一个项目列表 其中包含刻度日志 因此我设计的数据如下 清单 ticksheets JbN5ol2jGRtAOZ9ovrO auto ge
  • noscript 标签,如果未启用,我需要提供替代 html

    如果用户浏览器上未启用 JavaScript 是否可以用 HTML 替换 javascript 我知道我可以使用
  • 当以 C++03 为目标时,使用 std::basic_string 作为连续缓冲区是否合理?

    我知道在 C 03 中 从技术上讲std basic string模板不需要有连续的内存 然而 我很好奇现代编译器有多少实现实际上利用了这种自由 例如 如果有人想使用basic string要接收某些 C API 的结果 如下面的示例 分配
  • 是否可以从具有超时的输入流中读取?

    具体来说 问题是编写一个这样的方法 int maybeRead InputStream in long timeout 如果数据在 超时 毫秒内可用 则返回值与 in read 相同 否则返回 2 在该方法返回之前 任何生成的线程都必须退出
  • 您如何简单地解释类型转发?

    我正在准备 MCTS 70 536 阅读后this文章 我不确定我是否理解类型转发的概念 我发现文章中给出的步骤更加令人困惑 如果我复制要转发的类型的源代码并重新编译它 该怎么办 旧的 dll 和客户端会发生什么 类型转发允许您在程序集之间
  • 如何在Python中将日转换为年和月?

    如何在Python中将日转换为年 月和日 例如 如果某人已经 5 538 天了 我怎样才能通过这样的年月日来显示这一点 15岁2个月又1天 这是为了获取用户的输入 print Please enter your birthday bd ye
  • UICollectionView - 水平排列单元格

    所以基本上我的问题是我的集合视图单元格是从上到下排序的 而不是从左到右排序的 This is what it looks like 1 4 7 2 5 8 3 6 9 This is what i want 1 2 3 4 5 6 7 8
  • 需要在角度2中插入Script标签

    我已经做了一些阅读和搜索 几乎所有我发现的内容都表明脚本标签不能包含在 Angular 2 的模板中 我们会像您一样有意从模板中删除标签 不应该使用它们来按需加载代码 https github com angular angular iss
  • 特定元素是否存在事件

    是否有任何事件可以知道原始 javascript 中特定元素何时 开始存在 例如我有 div class parent div class child div div 我想在 parent 和只有 parent 不是 child 开始存在
  • 更快地绘制实时音频信号

    我有一段代码 它从笔记本电脑的音频插孔获取实时音频信号 并在进行一些基本过滤后绘制其图表 我面临的问题是 随着程序的运行 实时绘图变得越来越慢 有什么建议可以让绘图更快并以恒定的速度进行吗 我认为动画功能会使其更快 但无法根据我的要求制定
  • git diff 用于任何存储库之外的自定义 2 个文件?

    I need git diff我在任何存储库之外拥有的 2 个文件的功能 有办法做到吗 就像是git diff file1 path file1 txt file2 path file2 txt如果没有 替代解决方案是什么 答案就在the
  • 强制请求使用 IPv4 / IPv6

    如何强制requests库使用特定的互联网协议版本来获取请求 或者可以用Python中的另一种方法更好地实现这一点吗 我可以 但我不想使用curl 阐明目的的示例 import requests r requests get https m
  • 在 Woocommerce 3 中使用 WC_Cart add_to_cart() 方法存储自定义数据

    我正在创建一个会员网站 并为每个会员计划完全创建静态页面 只有 3 个计划 但是 我为每个计划添加了产品 当我点击 选择计划 按钮时 我会重定向到一些自定义表单 在其中询问用户我们将用于实现计划的信息范围 与sneakertub com相同
  • 如何使用 CGContext 获取像素的 RGB 值?

    我正在尝试通过更改像素来编辑图像 我有以下代码 let imageRect CGRectMake 0 0 self image image size width self image image size height UIGraphics
  • 出现编译错误时eclipse如何执行java代码

    当下面的java代码在eclipse中执行时 它给出了正确的输出 即打印 Class B 但根据java规范 代码无法编译 因为超类构造函数需要一个int编译器为类 B 提供的参数和构造函数包括对超类 无参数构造函数 的调用 该构造函数未定
  • JavaScript ES6 Promise for 循环

    for let i 0 i lt 10 i const promise new Promise resolve reject gt const timeout Math random 1000 setTimeout gt console l
  • 有没有办法将 pmml 文件导入到 python 中?

    我使用 sklearn 训练了一个模型 并使用 sklearn2pmml 将其导出为 pmml 格式 有没有办法将该 pmml 文件转换回可以在 python 中导入和运行的文件 我之所以这样做 是因为我注意到 pmml 模型与 sklea
  • Symfony2 Sonata 管理员根据所选值动态更改输入数据

    对于我的一个对象 我需要创建一些动态表单渲染 但我不知道如何在 Sonata Admin 中执行此操作 例如 当我创建一个对象时 我有一个字段类型 在此字段中 我选择我的对象的类型 现在 当我选择类型时 我想根据类型显示一个字段 例如 如果
  • `strtoul()` 对于非常“负”的字符串,正确的返回值是什么?

    这是一提出并回答自己的问题是可以的 我研究了这个问题 发现结果很奇怪 并发布了我的发现 非常负 的字符串应该返回什么值strtoul 1 ULONG MAX或者是什么 strtol 对于表示数值的字符串 例如 123 strtol 行为符合