简体   繁体   中英

Capitalize first letter of string

I am trying to capitalize the first character of a std::string , using the same method mentioned here . For example for the following program

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

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

I am expecting the output to be

Foobar

When I compile this online (using GCC 4.9.2) I get the correct output without any warnings . However, when I compile the same code in Visual Studio 2013, I get a warning during the assignment back from toupper

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

Is the above method valid according to the C++ standard or is the warning correct? Otherwise is this just a false warning by Visual Studio?

std::toupper comes from the C standard, not C++, and has an annoying interface in that it takes and returns an int not a char . Using static_cast<char>(std::toupper(name[0])) will suit you.

The warning is correct as far the types go; the type of std::toupper as defined in the standard is:

int toupper( int ch );

Mostly because it's a remnant from the dark C ages (the cctype header is a hint at that).

However, this is just a part of the story. There's another toupper residing in the locale header:

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

This one shouldn't give you any warnings. If you're not sure what locale to provide, std::locale() will give you the default one.

The warning is correct, compiler will implicitly cast from int to char but this might cause lost of data in some cases. To see warning under gcc you need to add -Wconversion compiler option. Which will generate:

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

Why it is not present when -Wall is set, read here:

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

Why isn't Wconversion enabled by -Wall or at least by -Wextra?

Implicit conversions are very common in C. This tied with the fact that there is no data-flow in front-ends (see next question) results in hard to avoid warnings for perfectly working and valid code. Wconversion is designed for a niche of uses (security audits, porting 32 bit code to 64 bit, etc.) where the programmer is willing to accept and workaround invalid warnings. Therefore, it shouldn't be enabled if it is not explicitly requested.

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