-5

I was converting string values into integer values with std::stoi() in my program when I noticed that it returned integer value of 25 from a string value of "25,".

This confused me because there is an exception thrown for invalid_argument when the string starts with anything but a number. For an example ",25" would throw an invalid_exception. Based on this I made the assumption that if the entire string value wasn't a number then an exception was thrown. This is not the case I come to realize. For an example "25,543" will return 25.

I ended up making my own function to call std::stoi() only if the entire string value is a number, otherwise, throw an invalid_argument exception.

With that said, I was wondering why it was designed this way or perhaps I don't understand how it works fully. I rather not keep using it if I am going to keep getting surprises like this realization.

Update: I checked the documentation from cppreference.com, I am just not experienced enough in to get it fully. I tried to reverse engineer the std::stoi definition but got the point where its was way above my level of experience. I posted this question with intent to both inform others of its functionality and the desire to know the nitty gritty.

  • 5
    Have you considered consulting the documentation? – user207421 Jul 31 '16 at 23:36
  • @Dimchtz No, I just tested it. I throws an exception if it starts with anything but a number. – ProfounDisputes Jul 31 '16 at 23:41
  • @EJP I did but to be honest it makes no sense to me. I am not that advanced for the vocabulary used here: http://en.cppreference.com/w/cpp/string/basic_string/stol Is there a different documentation that I don't know about? – ProfounDisputes Jul 31 '16 at 23:44
  • 3
    That is the documentation. If you can't understand it, try harder. You will get exactly nowhere in this business without being able to understand provided documentation, and you will certainly 'keep getting surprises' until you conquer this difficulty. But I don't see anything unclear about 'takes as many characters as possible to form a valid base-n (where n=base) integer number representation and converts them to an integer value', which answers your question completely. – user207421 Jul 31 '16 at 23:50
  • 1
    @ProfounDisputes `cppreference` always (except for some obscure topics) has a code sample illustrating the explained topic. That should help :) – Rakete1111 Jul 31 '16 at 23:51
  • @EJP I already spent some time looking at the definition of std::stoi and everything. It's not for lack of trying. I have seen people suggest using this but it's pretty important to mention that it has no protection from invalid characters. I posted for curiosity and to inform others. I have spent countless hours in documentation for other things. – ProfounDisputes Jul 31 '16 at 23:58
  • @Rakete1111 Is this post ambiguous? It's not that I don't understand how to use the function. I clearly shown that I know how to use it...just don't fully understand it, just curious. I already made a work around and everything... – ProfounDisputes Aug 01 '16 at 00:00
  • 2
    The documentation states clearly that it takes as many characters as possible that are digits in the specified radix. `,` is not a digit in any radix, so it stops there. Your surprise is incomprehensible. – user207421 Aug 01 '16 at 00:04
  • 2
    @ProfounDisputes I know that, but if you would have looked at the example you wouldn't have been surprised the behavior the function is exhibiting – Rakete1111 Aug 01 '16 at 00:11
  • @EJP It's clear the stackoverflow is not meant for entry level programmers. People don't want to deal with inexperience. You translated that into simple terms, that I haven't learned yet. So much abbreviations, terminology and methodologies I don't fully grasp yet. I have seen much more novice questions answered with less criticism. – ProfounDisputes Aug 01 '16 at 00:16
  • "_Why isn't everyone coddling me?_" Wow. – takendarkk Aug 01 '16 at 00:21
  • 3
    I haven't used any abbreviations at all, and there is nothing in the documentation you cited that is beyond any competent programmer. The issue here is not SO, it is your incomprehensible bafflement wih standard documentation. You are just going to have to overcome this, and online/interactive resources are not the way to do it. You should not have to ask questions here about basic stuff that is already documented in places you have already found. – user207421 Aug 01 '16 at 00:21
  • @EJP Thanks for translating it for me at least. Now I understand it but "You surprise is incomprehensible"? You don't know what I went through trying to figure that out. I am not a seasoned pro. I am telling you that documentation is not entry level programmer friendly. – ProfounDisputes Aug 01 '16 at 00:23
  • @takendarkk I don't like be coddled. It's just I couldn't understand it and you guys make it seem like I didn't try which isn't true. – ProfounDisputes Aug 01 '16 at 00:29
  • @takendarkk I get it though. You guys see hundreds, if not thousands, of stupid low effort questions. This question wasn't low effort. – ProfounDisputes Aug 01 '16 at 00:32
  • @EJP I wasn't saying you were confusing me I was talking about the documentation's abbreviations, terminology and methodologies. Also that is the point, man, I am not a competent programmer. I am just doing it on the side trying to get experience for landing a job in software development. – ProfounDisputes Aug 01 '16 at 00:33
  • 1
    I said nothing about your effort and everything about your reaction to negative comments. – takendarkk Aug 01 '16 at 00:35
  • @takendarkk I thought you knew what I meant. I know you said nothing of me that was your first comment haha – ProfounDisputes Aug 01 '16 at 00:37

1 Answers1

0

According to the C++ standard(N4296),

§ 21.5

21.5 Numeric conversions [string.conversions]

  1. Effects: the first two functions call strtol(str.c_str(), ptr, base), and the last three functions call strtoul(str.c_str(), ptr, base), strtoll(str.c_str(), ptr, base), and strtoull( str.c_str(), ptr, base), respectively. Each function returns the converted result, if any. The argument ptr designates a pointer to an object internal to the function that is used to determine what to store at *idx. If the function does not throw an exception and idx != 0, the function stores in *idx the index of the first unconverted element of str.
  2. Returns: The converted result.
  3. Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if strtol, strtoul, strtoll or strtoull sets errno to ERANGE, or if the converted value is outside the range of representable values for the return type.

What is strtol?

§ 21.8

21.8 Null-terminated sequence utilities [c.strings]

  1. Tables 74, 75, 76, 77, 78, and 79 describe headers <cctype>, <cwctype>, <cstring>, <cwchar>, <cstdlib> (character conversions), and <cuchar>, respectively.
  2. The contents of these headers shall be the same as the Standard C Library headers <ctype.h>, <wctype.h>, <string.h>, <wchar.h>, and <stdlib.h> and the C Unicode TR header <uchar.h>, respectively, with the following modifications:

Table 78 — Header <cstdlib> synopsis

Type Name(s)
Macros: MB_CUR_MAX
Functions:
atof mblen strtof strtoul
atoi mbtowc strtol strtoull
atol mbstowcs strtold wctomb atoll strtod strtoll wcstombs

What the meaning of Standard C Library?

§ 1.2

1.2 Normative references [intro.refs]

  1. The following referenced documents are indispensable for the application of this document. For dated references, only the edition cited applies. For undated references, the latest edition of the referenced document (including any amendments) applies.

    (1.3) — ISO/IEC 9899:1999, Programming languages — C
    (1.4) — ISO/IEC 9899:1999/Cor.1:2001(E), Programming languages — C, Technical Corrigendum 1
    (1.5) — ISO/IEC 9899:1999/Cor.2:2004(E), Programming languages — C, Technical Corrigendum 2

  2. The library described in Clause 7 of ISO/IEC 9899:1999 and Clause 7 of ISO/IEC 9899:1999/Cor.1:2001 and Clause 7 of ISO/IEC 9899:1999/Cor.2:2003 is hereinafter called the C standard library.1

So, we need to watch C99 standard.

According to the C99 standard(N1124)

§7.20.1.4

7.20.1.4 The strtol, strtoll, strtoul, and strtoull functions

  1. Description
    The strtol, strtoll, strtoul, and strtoull functions convert the initial portion of the string pointed to by nptr to long int, long long int, unsigned long int, and unsigned long long int representation, respectively. First, they decompose the input string into three parts: an initial, possibly empty, sequence of white-space characters (as specified by the isspace function), a subject sequence resembling an integer represented in some radix determined by the value of base, and a final string of one or more unrecognized characters, including the terminating null character of the input string. Then, they attempt to convert the subject sequence to an integer, and return the result.
  2. If the value of base is zero, the expected form of the subject sequence is that of an integer constant as described in 6.4.4.1, optionally preceded by a plus or minus sign, but not including an integer suffix. If the value of base is between 2 and 36 (inclusive), the expected form of the subject sequence is a sequence of letters and digits representing an integer with the radix specified by base, optionally preceded by a plus or minus sign, but not including an integer suffix. The letters from a (or A) through z (or Z) are ascribed the values 10 through 35; only letters and digits whose ascribed values are less than that of base are permitted. If the value of base is 16, the characters 0x or 0X may optionally precede the sequence of letters and digits, following the sign if present.
  3. The subject sequence is defined as the longest initial subsequence of the input string, starting with the first non-white-space character, that is of the expected form. The subject sequence contains no characters if the input string is empty or consists entirely of white space, or if the first non-white-space character is other than a sign or a permissible letter or digit.
  4. If the subject sequence has the expected form and the value of base is zero, the sequence of characters starting with the first digit is interpreted as an integer constant according to the rules of 6.4.4.1. If the subject sequence has the expected form and the value of base is between 2 and 36, it is 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 is negated (in the return type). A pointer to the final string is stored in the object pointed to by endptr, provided that endptr is not a null pointer.
  5. In other than the "C" locale, additional locale-specific subject sequence forms may be accepted.
  6. If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of nptr is stored in the object pointed to by endptr, provided that endptr is not a null pointer.
  7. Returns
    The strtol, strtoll, strtoul, and strtoull functions return the converted value, if any. If no conversion could be performed, zero is returned. If the correct value is outside the range of representable values, LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX, or ULLONG_MAX is returned (according to the return type and sign of the value, if any), and the value of the macro ERANGE is stored in errno.

Now we need to watch C++ standard again.

21.5 Numeric conversions [string.conversions]

  1. Throws: invalid_argument if strtol, strtoul, strtoll, or strtoull reports that no conversion could be performed. Throws out_of_range if strtol, strtoul, strtoll or strtoull sets errno to ERANGE, or if the converted value is outside the range of representable values for the return type.

Now you can understand when invalid_argument and out_of_range exception is thrown, I hope.

yumetodo
  • 1,147
  • 7
  • 19