大写首字母串

时间:2016-04-21 17:38:13

标签: c++ string visual-studio-2013

我正在尝试使用相同的方法mentioned here来大写std::string的第一个字符。例如,对于以下程序

#include <cctype>
#include <iostream>
#include <string>

int main()
{
    std::string name = "foobar";
    name[0] = std::toupper(name[0]);
    std::cout << name;
}

我期待输出

Foobar

当我compile this online(使用GCC 4.9.2)时,我得到正确的输出,没有任何警告。但是,当我在Visual Studio 2013中编译相同的代码时,我在从toupper

返回作业时收到警告
warning C4244: '=' : conversion from 'int' to 'char', possible loss of data

上述方法是否符合C ++标准或警告是否正确?否则这只是Visual Studio的错误警告?

3 个答案:

答案 0 :(得分:2)

std::toupper来自C标准,而不是C ++,并且有一个讨厌的界面,它需要并返回int而不是char。使用static_cast<char>(std::toupper(name[0]))将适合您。

答案 1 :(得分:2)

到目前为止,警告是正确的;标准中定义的std::toupper类型为:

int toupper( int ch );

主要是因为它是来自黑暗C年龄的残余物(cctype标题是对此的暗示)。

然而,这只是故事的一部分。 toupper标题中存在另一个 locale

template< class charT >
charT toupper( charT ch, const locale& loc );

这个不应该给你任何警告。如果您不确定要提供的区域设置,std::locale()将为您提供默认区域设置。

答案 2 :(得分:1)

警告是正确的,编译器将隐式地从int转换为char,但在某些情况下这可能会导致数据丢失。要查看gcc下的警告,您需要添加-Wconversion编译器选项。这会产生:

main.cpp: In function 'int main()':
main.cpp:8:13: warning: conversion to '__gnu_cxx::__alloc_traits<std::allocator<char> >::value_type {aka char}' from 'int' may alter its value [-Wconversion]
     name[0] = std::toupper(name[0]);
             ^
Foobar

设置-Wall时为什么不存在,请在此处阅读:

https://gcc.gnu.org/wiki/NewWconversion

  

为什么不通过-Wall或至少-wextra启用Wconversion?

     

隐含转换在C中非常常见。这与事实相关   前端没有数据流(见下一个问题)结果   很难避免完美工作和有效代码的警告。   Wconversion专为一系列用途而设计(安全审计,移植)   程序员愿意接受的32位代码到64位等   和解决方法无效警告。因此,如果不应该启用它   没有明确要求。