20

Is there a way to convert std::string to size_t? The problem is that size_t is platform dependable type (while it is the result of the sizeof). So, I can not guarantee that converting string to unsigned long or unsigned int will do it correctly.

EDIT: A simple case is:

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
Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160

6 Answers6

19

you can use std::stringstream

std::string string = "12345";
std::stringstream sstream(string);
size_t result;
sstream >> result;
std::cout << result << std::endl;
Yuriy Orlov
  • 786
  • 6
  • 12
11

You may want to use sscanf with the %zu specifier, which is for std::size_t.

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

Have a look here.

Literally, I doubt that there is an overloaded operator >> of std::basic_istringstream for std::size_t. See here.

Lingxi
  • 14,579
  • 2
  • 37
  • 93
  • I had to use the `%Iu` specifier but I develop on a for a Windows system. See [Working with the type size_t in the functions prinft, scanf and similar functions](http://www.viva64.com/en/k/0023/) – namatoj Feb 17 '17 at 11:29
9

Let us assume for a minute that size_t is a typedef to an existing integer, i.e. the same width as either unsigned int, unsigned long, or unsigned long long.

AFAIR it could be a separate (larger still) type as far as the standard wording is concerned, but I consider that to be highly unlikely.

Working with that assumption that size_t is not larger than unsigned long long, either stoull or strtoull with subsequent cast to size_t should work.


From the same assumption (size_t defined in terms of either unsigned long or unsigned long long), there would be an operator>> overload for that type.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • Tha is exactly what I am doing right now.. but I was wondering if there is a cleaner solution – Humam Helfawi Dec 02 '15 at 13:44
  • I'd plump for `%zd`: that's been around since the C99 standard. Not sure about C++ but I imagine it's been around fort the same amount of time. – Bathsheba Dec 02 '15 at 13:48
  • @Bathsheba: I have a deep, almost genetic dislike for the whole `*scanf()` family. I happen to have *implemented* them, so it's not a dislike-from-ignorance, but quite the opposite. I might *use* them in a pinch, but you will never see me *recommending* them to anyone, especially not in a C++ context. ;-) – DevSolar Dec 02 '15 at 13:51
  • I do agree with you although I cannot claim to have implemented the family myself. But I do feel that this particular case is an exception to the rule. Plus one, since you answer obviously contains hidden depths – Bathsheba Dec 02 '15 at 13:53
  • 1
    @Bathsheba: [Related SO question by myself, back from when I was implementing `*scanf()`](http://stackoverflow.com/questions/1425730). The summary is that the input string `"0xz"`, if parsed by `*scanf()`, is a matching failure *leaving the argument undefined* (and the input pointer being at `'x'`...) -- unless, of course, you're looking at a non-compliant implementation like glibc-2.8 or newlib 1.14. ;-) That's only *one* thing that made me detest `*scanf()`. ;-) – DevSolar Dec 02 '15 at 13:59
6

You can use %zd as the format specifier in a scanf-type approach.

Or use a std::stringstream which will have an overloaded >> to size_t.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • I doubt that there is an overloaded `operator >>` for `std::size_t`. See [here](http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt). – Lingxi Dec 02 '15 at 13:39
  • As I understood, There is no overload for size_t... but since Size_t is uint or ulong or ulongong... it would work for the right type of size_t ? – Humam Helfawi Dec 02 '15 at 13:43
  • Insofar that std::size_t will probably (perhaps certainly; need to check) be defined in terms of one of the primitive integral types, there will be. A compilation error would result if not. – Bathsheba Dec 02 '15 at 13:46
  • @Bathsheba: I only have the C99 paper here, but that doesn't say anything about `size_t` except where it is defined, that it is an unsigned integer type, the return type of `sizeof()`, and has a maximum value (`SIZE_MAX`) of no less than 65535. – DevSolar Dec 02 '15 at 14:24
  • Correct specifier for `size_t` is `%zu`, not `%zd`. – Aykhan Hagverdili Feb 13 '21 at 04:50
  • Also note that GCC defines size_t as `typedef __SIZE_TYPE__ size_t;` – Aykhan Hagverdili Feb 13 '21 at 04:52
1
#include <sstream>

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

By using iss.fail(), you check failure. Instead of ("a"), use value you want to convert.

Humam Helfawi
  • 19,566
  • 15
  • 85
  • 160
selin kamaş
  • 171
  • 1
  • 4
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;
    }
  }
Matheus Toniolli
  • 438
  • 1
  • 7
  • 16