简体   繁体   中英

c++ how to convert char to int while using `tolower`

I'm try to compile a simple expression:

char_to_int(tolower(row[y]))

However I'm getting the following errors when trying to compile it:

error: implicit conversion loses integer precision: 'int' to 'char' [-Werror,-Wimplicit-int-conversion]
                if (char_to_int(tolower(row[y])) > n

The signature of char_to_int is:

unsigned long char_to_int(char c)

and the type of row[y] is char .


Why am I getting this error and how can I fix it?

From your error information I assume you are using std::tolower from <cctype> (or equivalently, ::tolower from <ctype.h> ), not std::tolower from <locale> .

Why you are getting the error is straightforward from your error information: your char_to_int expects a char , but tolower returns an int . This will cause loss of information.

Why does tolower return an int , not just a char ? Because it can accept and return EOF, which may fall out of range of any char .

The fix can be straightforward: change your char_to_int to accept int , or do an intermediate step to discard the possible EOF.

std::tolower doesn't actually operate on char s: it operates on int s! Moreover, there is risk of undefined behaviour: if on your machine char is a signed type, then the "negative" characters will correspond to negative integers, which std::tolower is not equipped to deal with.

A way to fix this for your use is to manually cast the types before use:

char_to_int(static_cast<char>(
   std::tolower(static_cast<unsigned char>(row[y]))));

... which unfortunately is a bit of a mess, but that's what you have to do.

Alternatively, you may use the locale version of std::tolower , which is templated and will correctly handle char types. You may use it like so:

// std::locale{} is an object representing the default locale
// you may specify a locale precisely if needed; see the above links
char_to_int(std::tolower(row[y], std::locale{}));

tolower returns an int. std::tolower is however a template, and will work correctly for char. In general, if there is a std:: version of any func you are calling, use it! :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM