将字符串转换为size_t

21

有没有一种方法可以将 std::string 转换为 size_t?问题在于 size_t 是平台相关类型(尽管它是由 sizeof 的结果得出的)。因此,我不能保证将 string 转换为 unsigned longunsigned int 将正确完成。

编辑: 一个简单的例子是:

std::cout<< "Enter the index:";
std::string input;
std::cin >> input;
size_t index=string_to_size_t(input);
//Work with index to do something

3
string转换为size_t是指您试图将一组数字的字符串转换为无符号整数吗?请提供一些代码并解释您的问题。 - EdChum
请查看 http://en.cppreference.com/w/cpp/string/basic_string/stol - 0x6773
有什么阻止别人输入超过你的数字限制的巨大数字的方法吗? - EdChum
5
仅仅使用 size_t index; cin >> index; 有什么问题? - Šimon Tóth
@let_me_be,size_t的>>真的存在重载吗?请看Bathsheba的回答和评论。 - Humam Helfawi
显示剩余2条评论
6个回答

20

你可以使用std::stringstream

std::string string = "12345";
std::stringstream sstream(string);
size_t result;
sstream >> result;
std::cout << result << std::endl;

11

你可能想要使用带有%zu说明符的sscanf函数,该说明符适用于std::size_t类型。

sscanf(input.c_str(), "%zu", &index);

看看这里

实际上,我怀疑std::basic_istringstream没有针对std::size_t的重载operator >>。请参见此处


我不得不使用%Iu说明符,但我是在Windows系统上开发的。请参阅在prinft、scanf和类似函数中使用类型size_t - namatoj

9

假设 size_t 是一个已存在的整数类型的 typedef,即它与 unsigned intunsigned long 或者 unsigned long long 具有相同的位宽。

据我所知,标准措辞可能会将其视为一个单独的(更大的)类型,但我认为这种情况高度不可能发生。

在这个假设下,如果 size_t 不比 unsigned long long 更大,那么使用 stoull 或者 strtoull 并随后强制转换为 size_t 应该可以解决问题。


在同样的假设下(size_t 定义为以 unsigned long 或者 unsigned long long 为基础),就应该存在一个针对该类型的 operator>> 重载。


这正是我现在正在做的事情...但我想知道是否有更简洁的解决方案。 - Humam Helfawi
我会选择%zd:自 C99 标准以来就存在了。不确定 C++ 是否也是如此,但我想它与 C 的存在时间相同。 - Bathsheba
@Bathsheba:我对整个*scanf()家族有一种深刻的、几乎是基因级别的厌恶。我碰巧实现了它们,所以这不是出于无知而产生的厌恶,而是相反的。在紧急情况下,我可能会使用它们,但你永远不会看到我向任何人推荐它们,特别是在C++环境中。;-) - DevSolar
我同意你的看法,尽管我不能声称自己已经实现了这个家族。但我确实认为这种情况是一个例外。再加一分,因为你的回答显然包含了深层次的含义。 - Bathsheba
1
@Bathsheba: 关于我自己的相关 SO 问题,当时我正在实现 *scanf()。总结一下,如果使用 *scanf() 解析输入字符串 "0xz",则匹配失败,参数未定义(输入指针在 'x' 处……)——除非你使用像 glibc-2.8 或 newlib 1.14 这样不合规范的实现。;-) 这只是让我厌恶 *scanf()一件事情。;-) - DevSolar

6

您可以在类似于scanf的方法中使用%zd作为格式说明符。

或者使用std::stringstream,它将具有重载的>>以转换为size_t


我怀疑std::size_t没有重载的operator >>。请参考这里。 - Lingxi
据我所理解,size_t 没有重载...但是由于 Size_t 是 uint 或 ulong 或 ulongong...它将适用于正确类型的 size_t? - Humam Helfawi
只要std::size_t可能(也许肯定;需要检查)是基本整数类型之一定义的,那么就会有。如果不是,则会导致编译错误。 - Bathsheba
@Bathsheba:我这里只有C99的文件,但是它并没有详细说明size_t除了在哪里定义之外的任何信息。它是一个无符号整数类型,是sizeof()的返回类型,并且具有不小于65535的最大值(SIZE_MAX)。 - DevSolar
size_t 的正确格式说明符是 %zu,而不是 %zd - Ayxan Haqverdili
请注意,GCC将size_t定义为typedef __SIZE_TYPE__ size_t; - Ayxan Haqverdili

1
/**
   * @brief  Convert const char* to size_t
   * @note   When there is an error it returns the maximum of size_t
   * @param  *number: const char* 
   * @retval size_t
   */
  size_t to_size_t(const char *number) {
    size_t sizeT;
    std::istringstream iss(number);
    iss >> sizeT;
    if (iss.fail()) {
      return std::numeric_limits<size_t>::max();
    } else {
      return sizeT;
    }
  }

1
#include <sstream>

std::istringstream iss("a");
size_t size;
iss >> size;

通过使用iss.fail(),您可以检查失败情况。不要使用("a"),而是使用您想要转换的值。

我认为你的意思是 >>,而不是 >。 - Bathsheba

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