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

时间:2016-09-06 12:29:10

标签: c++ c++11

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

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',可能会丢失数据?

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

4 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:2)

明确地将其投放到char

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

toupper()被定义为返回int,这就是您的编译器对您大吼大叫的原因。在这种情况下,你确切地知道你正在做什么,你只需要说服一下编译器。

答案 2 :(得分:1)

完全一般性地,

toupper需要处理EOF,这就是为什么它需要int作为参数并返回int

我倾向于掩盖这种复杂性并写下

#include <algorithm>
std::transform(str.begin(), str.end(), str.begin(), ::toupper);

代替,并关闭编译此代码的警告。

答案 3 :(得分:0)

我有一个类似的问题,并且由于我正在使用的代码正在使用-Wall,所以我收到有关整数的警告,以防止可能丢失数据。现在我可以简单地进行下去了:

std::string s = "Hello World";

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

但这只是唯一,因为我可以保证我要处理的是纯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)); });