如何从字符串中获取size_t?

11

我需要从用户输入中获取一个数组大小。对我来说,将输入存储为 size_t 似乎是很自然的选择,但是当我寻找合适的 strto...() 函数时,却没有找到任何一个适用于 size_t 的函数。因此,我只好使用 strtoull(),因为 unsigned long long 至少保证具有 64 位,并且我正在使用 C99。但是,我想知道从字符串中获取 size_t 的最佳方法是什么——比如,在 ANSI C 中。

编辑:

为了澄清,我不需要字符串长度!用户将以字符串形式输入大缓冲区的大小,例如 "109302393029"。我需要获取该数字并将其存储为 size_t。当然,我可以使用 strtol() 或甚至 atoi(),但这似乎是一个笨拙的方法(size_t 可能容纳比 int 更大的值,而且我希望用户能够输入可寻址空间中的任何值)。


1
strlen 对于指向数组的指针无效。 - Tim Biegeleisen
1
您可以使用 unsigned long long 作为变量类型。似乎 size_t 不太可能比它更大。 - M.M
1
可能是printf格式说明符适用于uint32_t和size_t的重复问题。 - perreal
3个回答

16

如果您有一个包含 size_t 值的字符串输入,并想要获取该值,您可以使用带有 %zu 格式说明符的 sscanf() 函数来读取该值并将其存储到相应的 size_t 变量中。

注意:不要忘记检查 sscanf() 和其相关函数的成功执行。

伪代码:

size_t len = 0;
if (1 == sscanf(input, "%zu", &len))
printf("len is %zu\n", len);

不过,顺便提一下,这种方法无法处理溢出的情况。在输入长度是任意大的情况下(您的程序应该能够处理),您可能需要使用strtoumax()并检查是否发生了溢出,最后将返回值强制转换为size_t。请参阅Mr. Blue Moon的相关答案


然而,如果您不介意另一种方法,可以直接将输入作为size_t进行处理,而不是将其作为字符串并将其转换为size_t,例如:

size_t arr_size = 0;
scanf("%zu", &arr_size);

4
他也可以将输入作为字符串,并使用“sscanf”。 - M.M
这种方法的问题在于它不安全,容易出现整数溢出问题,考虑到 OP 想要处理任意大的输入。 - P.P
@BlueMoon 先生,我想您是指“_不安全_”,这很正确。在溢出/下溢的情况下需要进行范围检查。我会在我的回答中添加关于strtoumax()的段落。感谢您的建议。 :) - Sourav Ghosh
是的。我已经使用 strtoumax 方法添加了一个答案。 - P.P

5

您可以使用strtoumax()函数进行转换:

   #include <inttypes.h>

   intmax_t strtoimax(const char *nptr, char **endptr, int base);
   uintmax_t strtoumax(const char *nptr, char **endptr, int base);

把结果转换为size_t类型是更好的方法,因为它可以帮助检测到给定任意大的输入时的溢出情况。

scanf()系列函数无法检测整数溢出,这会导致未定义行为


“...并将结果转换为size_t。” 在 “SIZE_MAX < UINTMAX_MAX” 时会省略检测溢出。 它也无法检测负数输入。 - chux - Reinstate Monica

2
只需将输入作为无符号整数获取并将其转换为size_t,或者只需执行以下操作:
size_t length;
scanf("%zu", &length);

2
他正在使用 c99,因此指定符号 '%zu' 更适合于 size_t - ameyCU

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接