警告 C4244 \ '=':从 'int' 转换为"char",可能会丢失数据?

Warning C4244 '=': conversion from 'int' to 'char', possible loss of data?

本文关键字:数据 转换 C4244 int 警告 char      更新时间:2023-10-16

在编写解决一个谜题的程序时,我在以下代码片段中遇到了警告:

std::string str = "hello";
for (int i = 0; i < str.length(); ++i)
    str[i] = toupper(str[i]); //make every letter capital       
//  ^^ warning

我在上面的最后一行得到一个警告。

警告C4244 '=':从'int'转换为'char',可能丢失数据?

有没有办法摆脱这个警告?

str[i]显式转换为char:

str[i] = (char)toupper(str[i]);

或:

str[i] = static_cast<char>(toupper(str[i]));

使操作更加c++友好。std::toupper返回一个int,这会使编译器报错。通过强制转换返回值,你告诉编译器你知道你在做什么。

作为旁注,我建议立即对字符串使用boost::to_upper(),如下所示:

#include <boost/algorithm/string.hpp>
#include <string>
std::string str = "hello";
boost::to_upper(str); //Is HELLO
std::string newstr = boost::to_upper_copy<std::string>("hello"); //is HELLO

将其显式转换为char:

str[i] = (char)toupper(str[i]);

toupper()被定义为返回int,这就是为什么你的编译器会对你大喊大叫。在这种情况下,你知道你在做什么,你只需要说服编译器,一点点。

我有一个类似的问题,因为我正在工作的代码是使用-Wall,我得到关于int到char可能丢失数据的警告。现在我可以使用一个简单的:

std::string s = "Hello World";
for (char& c : s)
{
    if (c >= 'a' && c <= 'z)
       c &= 0x20;
}

但是这是ONLY,因为我可以保证我正在处理的是纯ASCII,而不会是其他任何东西。正如其他人所提到的,使用std::transform()::toupper()可能更好。我对他们的特定答案的唯一问题是,他们建议关闭使用这种方法会得到的警告。您仍然可以得到它们,因为::toupper()::tolower()转换后都返回int。

所以我最终得到的是两全其美,就是像下面这样转换::toupper的返回代码。这意味着我不必为这个转换禁用警告。

std::string s = "Hello World";
std::transform(s.begin(), s.end(), s.begin(), [](int c) -> char { return static_cast<char>(::tolower(c)); });

toupper一般需要处理EOF,这就是为什么它以int作为参数并返回int的原因。

我倾向于把这种复杂性隐藏起来,写

#include <algorithm>
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
为编译此代码关闭警告。