C++ Atoi can't handle special characters

Im using this atoi to remove all letters from the string. But my string uses special characters as seen below, because of this my atoi exits with an error. What should I do to solve this?

#include <iostream>
#include <string>
using namespace std;
 
int main() {
    std::string playerPickS = "Klöver 12"; // string with special characters
 
    size_t i = 0;
    for (; i < playerPickS.length(); i++) { if (isdigit(playerPickS[i])) break; }
 

    playerPickS = playerPickS.substr(i, playerPickS.length() - i); // convert the remaining text to an integer
 
    cout << atoi(playerPickS.c_str());
 
}

This is what I believe is the error. I only get this when using those special characters, thats why I think thats my problem.

assert failure

Upvotes: 0

Views: 429

Answers (2)

MSalters
MSalters

Reputation: 179991

char can be signed or unsigned, but isidigt without a locale overload expects a positive number (or EOF==-1). In your encoding 'ö' has a negative value. You can cast it to unsigned char first: is_digit(static_cast<unsigned char>(playerPickS[i])) or use the locale-aware variant.

Upvotes: 3

catnip
catnip

Reputation: 25388

atoi stops scanning when it finds something that's not a digit (roughly speaking). So, to get it to do what you want, you have to feed it something that at least starts with the string you want to convert.

From the documentation:

[atoi] Discards any whitespace characters until the first non-whitespace character is found, then takes as many characters as possible to form a valid integer number representation and converts them to an integer value. The valid integer value consists of the following parts:

  • (optional) plus or minus sign
  • numeric digits

So, now you know how atoi works, you can pre-process your string appropriately before passing it in. Good luck!


Edit: If your call to isdigit is failing to yield the desired result, the clue lies here:

The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.

So you need to check for that yourself before you call it. Casting playerPickS[i] to an unsigned int will probably work.

Upvotes: 1

Related Questions