0

I am kind of beginner in C++ and I want a simple way to convert a char string (char * str1) to an integer. I am able to do that with atoi, but I have read that this function is "devil" and should not be used. I don't want to use C++ std:string for many reasons, so my string must be in char* format. Do you have any suggestions?

Thanks in advance

3
  • 2
    Claiming that atoi is "[the] devil" might be a little to strong. It doesn't have very much error checking or validation, if that's what you want. Then you could use std::stoi instead. Commented Nov 19, 2018 at 9:16
  • 4
    On an unrelated note: "I don't want to use C++ std:string for many reasons" you say, and I'll wager that most if not all of them are bad or wrong. Commented Nov 19, 2018 at 9:23
  • strtol() is another option with more error-checking options. However I'd recommend you to use std::string and std::stoi Commented Nov 19, 2018 at 9:24

4 Answers 4

2

As an alternative, still C-style, use sscanf:

/* sscanf example */ #include <stdio.h> int main () { char sentence []="Rudolph is 12 years old"; char str [20]; int i; sscanf (sentence,"%s %*s %d",str,&i); printf ("%s -> %d\n",str,i); return 0; } 

[EDIT] As reported by @Killzone Kid in the comment, there is an std version.

#include <iostream> #include <clocale> #include <cstdio> int main() { int i, j; float x, y; char str1[10], str2[4]; wchar_t warr[2]; std::setlocale(LC_ALL, "en_US.utf8"); char input[] = u8"25 54.32E-1 Thompson 56789 0123 56ß水"; // parse as follows: // %d: an integer // %f: a floating-point value // %9s: a string of at most 9 non-whitespace characters // %2d: two-digit integer (digits 5 and 6) // %f: a floating-point value (digits 7, 8, 9) // %*d an integer which isn't stored anywhere // ' ': all consecutive whitespace // %3[0-9]: a string of at most 3 digits (digits 5 and 6) // %2lc: two wide characters, using multibyte to wide conversion int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc", &i, &x, str1, &j, &y, str2, warr); std::cout << "Converted " << ret << " fields:\n" << "i = " << i << "\nx = " << x << '\n' << "str1 = " << str1 << "\nj = " << j << '\n' << "y = " << y << "\nstr2 = " << str2 << '\n' << std::hex << "warr[0] = U+" << warr[0] << " warr[1] = U+" << warr[1] << '\n'; } 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks, I did not know it. I added it to the answer.
I don't know if replacing atoi with sscanf is such an improvement. Although quite versatile, it does carry it's own bag of gotchas.
I totally agree. The question is not really clear on the reasons behind the choice of using C-style strings, or not using atoi. So I just suggested an alternative, as requested.
1

You should use C++ stoi (https://en.cppreference.com/w/cpp/string/basic_string/stol):

int main() { std::cout << std::stoi("123"); } 

Of course, you should pass a pos argument to see if the string was converted entirely or not.

Comments

0

C++ style, but without string:

#include <iostream> #include <sstream> int str2i(const char *str) { std::stringstream ss; ss << str; int i; ss >> i; return i; } int main() { std::cout << str2i("123"); } 

Comments

0

You need to consider the reason why atoi is considered unsafe. There is no way to know if the conversion worked.

A similar C function function is strol. To use it you would do the following:

char* input_string = ... char* end = nullptr; long value = strol(input_string, &end, 10); if (input_string == end) { // converison failed } 

Alternatively, if you are programing C++ and not C, you can use one of my generic read functions:

template <typename T> T from_string(const std::string_view str) { std::stringstream buff(str); T value; buff >> value; // check if all input was consumed if (buff.gcount() != str.size()) { throw std::runtime_exception("Failed to parse string."); } return value; } 

This can then be used on anything that has a stream in operator. In your case:

 const char* int_string = "1337"; int int_value = from_string<int>(int_string ); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.