- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
根据 strtol
的规范:
If the subject sequence has the expected form and the value of base is 0, the sequence of characters starting with the first digit shall be interpreted as an integer constant. If the subject sequence has the expected form and the value of base is between 2 and 36, it shall be used as the base for conversion, ascribing to each letter its value as given above. If the subject sequence begins with a minus-sign, the value resulting from the conversion shall be negated. A pointer to the final string shall be stored in the object pointed to by endptr, provided that endptr is not a null pointer.
手头的问题是,在否定之前,该值不在 long
的范围内。例如,在 C89 中(整型常量不能取long long
类型),写-2147483648
可能是溢出;你必须写 (-2147483647-1)
或类似的。
由于使用“整数常量”的措辞可以解释为将 C 规则应用于整数常量的类型,这可能足以使我们免于此处的未定义行为,但同样的问题(没有这么容易解决)将应用于 strtoll
。
最后,请注意,即使确实溢出,也应该返回“正确”的值。所以这个问题实际上只是关于在这种情况下是否可以或必须设置 errno
。
最佳答案
虽然我今天无法指出标准中的特定措辞,但当我为 4BSD 编写 strtol
时早在 1990 年代,我就非常确定这不应该设置errno
,并确保我不会。这是基于标准中的措辞,还是与某人的个人讨论,我已记不清了。
为了避免溢出,这意味着必须非常小心地进行计算。我在 unsigned long
中完成了它并包含了这个注释(仍然在各种 BSD 的 libc
源代码中):
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set 'any' if any `digits' consumed; make it negative to indicate
* overflow.
*/
我曾经(并且在某种程度上仍然)对 C 库中的此操作与语言本身的语法之间的不对称感到恼火(其中负数是两个单独的标记,-
紧随其后通过数字,所以写 -217483648
意味着 -(217483648)
变成 -(217483648U)
这当然是 217483648U
因此是肯定的!(当然假设 32 位 int
;有问题的值因其他位大小而异。)
关于c - 如果 LONG_MAX 为 2147483647,strtol ("-2147483648", 0, 0) 是否溢出?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17003270/
我编写了以下词法分析器。它适用于以下输入:c&3&f、(3|6)&c、f^1。然而,我得到的 strtol 结果并不一致。当我运行 #include #include //Max number
我正在使用 strtol 从字符串中解析整数。我打算使用 strtol 的第二个参数来确定整个字符串是否被解析为数字。我有这样的代码(字符串永远不会代表 token; const size_t tok
strtol 规范在概念上将输入字符串分为“初始空白”、“主题序列”和“最终字符串”,并将“主题序列”定义为: the longest initial subsequence of the input
我只是好奇这个。 strtol 不需要您指定要处理的字节数,因此理论上它可能会被提供一个包含无穷无尽的数字序列的字符串以供使用,从而导致拒绝服务攻击。当然,一旦意识到 long 的精度已经用尽(实际上
关闭。这个问题需要 details or clarity 。目前不接受答案。 想要改进这个问题?通过 editing this post 添加详细信息并澄清问题。 已关闭 5 年前。 奥 git _a
这周我刚刚开始学习c。 我正在尝试将单个字符转换为 long/int。 我的问题是,当我通过 main 调用 convenrtCharToInt 时,它返回正确的值,但是当我通过另一个函数调用此函数,
我有这段代码,应该可以正常运行,但由于某种原因,当我在循环的条件检查之前释放字符串时,循环会循环。摆脱循环的唯一方法是给出超过 3 位的整数(输入 > 99 || 输入 #include #inc
当我使用 strtol() 函数时,当我尝试转换时: 2015-08-12 我希望它转换失败而不是仅转换 2015? int main(int argc, char *argv[]) { p
使用指针: char a[]=" 0xa this is a343 good"; char* *endptr=NULL; long int b=0; b=strtol(a,endptr,0); b=s
您好,我制作了一个测试程序,以便在我对以下代码使用 valgrind --track-origins=yes -v ./a.out 时获得如何解决问题的帮助它返回以下错误; ==13192== 1 e
有人可以帮助我理解为什么我看到相同输入的不同输出吗? “n”的输出是 2147483647,这是不正确的。为什么? --------输出------------ FF FF FF FF FFFFFF
strtol 的第二个参数是如何工作的? 这是我尝试过的: strtol(str, &ptr, 10) 其中 ptr 是一个 char * 而 str 是一个字符串。现在,如果我将 str 作为 '3
所以我有两个十六进制字符串 - "3b101c091d53320c000910" 和 "071d154502010a04000419"。当我对它们使用 strtol() 时,我得到两个字符串的相同值。
我正在尝试使用以下代码使用 strtol 将字符数组转换为整数: int foo = strtol(temp, (char **)NULL, 0); 其中温度 = 4000000010 但是 strt
这个问题在这里已经有了答案: strtol using errno (5 个答案) 关闭 8 年前。 基本上使用 strtol 来检查不成功的转换,我正在使用函数 width = (int) st
我真的很困惑。我必须遗漏一些相当简单的东西,但我读到的关于 strtol() 的内容没有任何意义。有人可以用一种非常基本的方式为我阐明它,并举例说明我如何使类似以下的东西起作用吗? string in
根据 C11 (n1570) 中的 § 7.22.1.4,必须声明 strtol: #include long int strtol (const char *restrict nptr,
此代码似乎按预期工作,使用单个指针填充数字数组 #include #include #include int main(void) { int arr[4], count = 0, i;
我这里有一个奇怪的。当我传入以下字符串时,strtol、atol 和 atoi 都返回不正确的值: long test = strtol("3087663490", &p, 10); 根据我的调试器,
我正在围绕 strtol() 创建一个包装函数对于 int16_t ,我遇到了一个问题:如何处理 0x 这样的输入?也就是说,它作为数字有效吗 0 , 后跟非数字 x , 或者它是无效的因为后面没有任
我是一名优秀的程序员,十分优秀!