在编写解决谜题的程序时,我在以下代码段中遇到警告:
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',可能会丢失数据?
有没有办法摆脱这种警告?
答案 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)); });