Thread: please explain me the different behaviours related to toupper/string

  1. #1
    Registered User
    Join Date
    Jan 2014
    Posts
    76

    please explain me the different behaviours related to toupper/string

    in this 1st code t[0] return 'char' so the compiler throws an error illegal conversion from 'char' to 'const char*' :

    Code:
    //CODE 1
    
    #include<iostream>              
    #include<vector>
    #include<cctype>
    #include<string>
    
    
    using namespace std;
    
    
    int main()
    {
            string t="hello";
    /* If I had used 'toupper([0])' for direct initialization of string 's', it would have thrown error -> illegal conversion from int to const char* */
            string s(t[0]);
            return 0;
    }
    but in the second code I have used a vector of string type which I have changed from lower case to upper:

    Code:
    //CODE 2
    #include<iostream>
    #include<vector>
    #include<cctype>
    #include<string>
    
    
    using namespace std;
    
    
    int main()
    {
            vector<string> vec(1,"hello");
            for(vector<string>::size_type j=0;j<vec[0].size();j++)
            {
                    vec[0][j]=toupper(vec[0][j]);
            }
            cout<<vec[0]<<endl;
            return 0;
    }
    this 2nd code is accepting 'int' returned by toupper and vector of string type is accepting it without any error why this dual behavior?

    Or is it due to the int-to-char natural/automatic conversion is taking place due to vec[0][j] indicating a 'char'?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by gaurav#
    If I had used 'toupper([0])' for direct initialization of string 's', it would have thrown error -> illegal conversion from int to const char*
    toupper([0]) doesn't make sense at all. What exactly did you try, and what was the exact error message?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jan 2014
    Posts
    76
    The error message when I use toupper(t[0]) is:
    k.cpp:11:23: error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive] string s(toupper(t[0]));
    without using it, it is:
    k.cpp: In function ‘int main()’:k.cpp:11:15: error: invalid conversion from ‘char’ to ‘const char*’ [-fpermissive]
    string s(t[0]);

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I think you mean
    string t = "hello";
    t[0] = toupper(t[0]);


    Maybe if I knew what you were really doing there would be more to this.

  5. #5
    Registered User
    Join Date
    Jan 2014
    Posts
    76
    nope, I am doing exactly what I have done, i.e. direct initialization of string 's' in code 1 and conversion to upper case in code 2.

  6. #6
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Well, string does not have a constructor that is just one char argument, so statements like this will always fail for one reason or another.
    string s(
    toupper(t[0]));

    If you want string s to be Hello, I recommend modifying t and then simply doing
    string s = t;

  7. #7
    Registered User
    Join Date
    Jan 2014
    Posts
    76
    Well, string does not have a constructor that is just one char argument, so statements like this will always fail for one reason or another.
    string s(
    toupper(t[0]));
    the point of issue is: in code 1 the integer returned by toupper is rejected for initialization and in code 2 it is accepted -> in both the cases strings are involved.

    maybe this clears better (from CODE 2):
    is it due to the int-to-char natural/automatic conversion is taking place due to vec[0][j] indicating a 'char'?

  8. #8
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    You're thinking the wrong way about code 2 in general. Initialization is not even being used in code 2. What happens is vec[0] is a reference to a string in the array and then [j] acts upon that reference, so, you access character j of string 0 in vec.

  9. #9
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    OP: the version of toupper you're using returns an int: http://www.cplusplus.com/reference/cctype/toupper/for what you're trying to do use the one that uses std::locale: http://www.cplusplus.com/reference/locale/toupper/

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Quote Originally Posted by sean_cantab View Post
    OP: the version of toupper you're using returns an int: 404 Page Not Found what you're trying to do use the one that uses std::locale: http://www.cplusplus.com/reference/locale/toupper/
    Well, other than being locale-aware, it doesn't solve the problem he had.

  11. #11
    Registered User
    Join Date
    Mar 2016
    Posts
    203
    from OP:
    Code:
     string s(t[0]);
    understood this as OP wanted a single letter string which was == "H" if s/he'd been successful with the toupper() interim conversion. so this could be one solution:
    Code:
    #include <iostream>
    #include <string>
    #include <locale>
    
    
    int main()
    {
        std::locale loc{};
        std::string t = "HelloWorld";
        std::string s (1, (std::toupper(t[0], loc)));
        std::cout << s << "\n";
    }
    but yes, of course, this could be done with the non-locale version of toupper as well:
    Code:
    #include <iostream>
    #include <string>
    #include <cctype>
    
    
    int main()
    {
        std::string t = "HelloWorld";
        std::string s (1, (std::toupper(t[0])));
        std::cout << s << "\n";
    }
    However noticed something interesting for the second version: if using braced-initialization: there are narrowing conversion warnings here Coliru Viewer to out-right error messages on my gcc 5.9.2
    the first version, using std::locale, runs with braced-initialization without errors or warnings but produces a garbage character in front: Coliru Viewer
    it seems for both versions calling the std::string ctor with parentheses produces the desired output but not with braced initialization

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    if using braced-initialization: there are narrowing conversion warnings
    Yes, because you're trying to implicitly convert the int returned by toupper() to a char. The initialization list expects the types to match exactly. You need to explicitly cast the value returned from toupper() to a char, ie: static_cast<char>(::toupper(t[0])).

    The locale aware version returns a charT, not an int.

    Jim
    Last edited by jimblumberg; 03-13-2017 at 01:58 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Strange behaviours
    By Kempelen in forum C Programming
    Replies: 1
    Last Post: 08-13-2012, 07:26 AM
  2. string operation and related exception
    By George2 in forum C++ Programming
    Replies: 63
    Last Post: 03-04-2008, 02:54 AM
  3. Help Converting a String to uppercase using TOUPPER()
    By frgmstr in forum C++ Programming
    Replies: 4
    Last Post: 10-31-2001, 01:56 PM
  4. Help on toupper string
    By programmer in forum C++ Programming
    Replies: 5
    Last Post: 10-07-2001, 01:07 AM
  5. Help on toupper string
    By cooleeze in forum C++ Programming
    Replies: 2
    Last Post: 10-06-2001, 01:32 PM

Tags for this Thread