Thread: Cout of unsigned char

  1. #1
    Registered User
    Join Date
    Dec 2019
    Posts
    20

    Cout of unsigned char

    I'm using Visual Studio 2019: why does this command do nothing?

    Code:
    std::cout << unsigned char(133);
    It literally gets skipped by my compiler (I verified it using step-by-step debug):
    I expected a print of `à`.
    Every output before the next command is ignored, but not the previous ones. (std::cout << "12" << unsigned char(133) << "34"; prints "12")


    I've also tried to change it to these:
    Code:
    std::cout << unsigned char(133) << std::flush;
    std::cout << (unsigned char)(133);
    std::cout << char(-123);
    but the result is the same.


    I remember that it worked before, and some of my programs that use this command have misteriously stopped working... In a blank new project same result!


    I thought that it my new custom keyboard layout could be the cause, but disabling it does not change so much.


    On other online compilers it works properly, so may it be a bug of Visual Studio 2019?

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    It should be:
    Code:
    #include <iostream>
     
    int main() {
        std::cout << "12" << static_cast<unsigned char>(133) << "34" << '\n';
     
        // or
        std::cout << "12" << (unsigned char)(133) << "34" << '\n';
     
        // or
        using uchar = unsigned char;
        std::cout << "12" << uchar(133) << "34" << '\n';
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

  3. #3
    Registered User
    Join Date
    Dec 2019
    Posts
    20
    Quote Originally Posted by john.c View Post
    It should be:
    Code:
    #include <iostream>
     
    int main() {
        std::cout << "12" << static_cast<unsigned char>(133) << "34" << '\n';
     
        // or
        std::cout << "12" << (unsigned char)(133) << "34" << '\n';
     
        // or
        using uchar = unsigned char;
        std::cout << "12" << uchar(133) << "34" << '\n';
    }
    None of these work... I always get "12" and nothing else

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    Quote Originally Posted by Foxel View Post
    None of these work... I always get "12" and nothing else
    Doesn't seem possible, does it.
    Did you start a new project, copy paste the code, and run it?
    A little inaccuracy saves tons of explanation. - H.H. Munro

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    What exactly are you expecting to print with the unsigned char 133?

    What operating system are you using, what compiler?

    If on Windows, what code page are you using?

  6. #6
    Registered User
    Join Date
    Dec 2019
    Posts
    20
    Quote Originally Posted by jimblumberg View Post
    What exactly are you expecting to print with the unsigned char 133?

    What operating system are you using, what compiler?

    If on Windows, what code page are you using?
    As I said in the question, I expected a print of "à" (133th UTF-16 symbol), but the same thing happens with any extended ASCII char.

    I'm using Visual Studio 2019 on Windows and running it on the Command Prompt (but I've also tried with PowerShell)
    Last edited by Foxel; 02-06-2020 at 09:24 AM.

  7. #7
    Registered User
    Join Date
    Dec 2019
    Posts
    20
    Quote Originally Posted by john.c View Post
    Doesn't seem possible, does it.
    Did you start a new project, copy paste the code, and run it?
    As I said in the question, I have already tried but nothing changes. It only works if I use an online compiler like Dcoder

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    Quote Originally Posted by Foxel View Post
    As I said in the question, I have already tried but nothing changes. It only works if I use an online compiler like Dcoder
    How about if you just use char instead of unsigned char?

    (And you never said anything about trying it in a new project, so I asked.)
    A little inaccuracy saves tons of explanation. - H.H. Munro

  9. #9
    Registered User
    Join Date
    Dec 2019
    Posts
    20
    Quote Originally Posted by john.c View Post
    How about if you just use char instead of unsigned char?
    Quote Originally Posted by Foxel View Post
    I've also tried to change it to this:
    Code:
    std::cout << char(-123);


    Quote Originally Posted by john.c View Post
    (And you never said anything about trying it in a new project, so I asked.)
    Quote Originally Posted by Foxel View Post
    In a blank new project same result!
    Please read entirely my question before answering
    Last edited by Foxel; 02-06-2020 at 09:22 AM.

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    Quote Originally Posted by Foxel View Post
    Please read entirely my question before answering
    It is not in your interest to be a dick.
    I spent the last 10 minutes finding the answer, but now I don't feel like posting it.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  11. #11
    Registered User
    Join Date
    Dec 2019
    Posts
    20
    Quote Originally Posted by john.c View Post
    It is not in your interest to be a dick.
    I spent the last 10 minutes finding the answer, but now I don't feel like posting it.
    I don't wanna be a dick, but I feel teased if you ask me something I've already said and, after I point it out, you ask another thing mentioned in the question...
    Last edited by Foxel; 02-06-2020 at 09:50 AM.

  12. #12
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Also here -> Cout of unsigned char - C++ Forum

    You could try say
    Code:
    ofstream of("output.txt");
    of << "12" << (unsigned char)(133) << "34" << '\n';
    and verify using a hex editor whether the character
    a - appears at all
    b - appears, but perhaps re-encoded as something else.

    Or even just redirecting the stdout of your existing program might show something as well.

    Also, consoles have these messy things called code pages in windows, which generally muck about with the interpretation of bytes which are anything other than 7-bit ASCII.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  13. #13
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by Salem View Post
    Also, consoles have these messy things called code pages in windows, which generally muck about with the interpretation of bytes which are anything other than 7-bit ASCII.
    A few years back, I read that printf worked better than cout on windows when doing something other than 7 bit ASCII.

    No idea if that is still true and it might only apply to mingw GCC.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  14. #14
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    I was able to recreate the problem and then fix it again.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  15. #15
    Registered User
    Join Date
    Nov 2018
    Location
    Amberg in upper palatinate, Bavaria
    Posts
    66
    Hi Foxel!

    The normal characters of a string are between 32(space) and 127.
    It is possible that some systems have an other length for different characters. See UTF8 by Wikipedia
    Code:
    //converts a signed char to int
    int atoint(char letter)
    {
     int rewer;
     if ( letter < 0)
      rewer = letter + 256;
       else rewer = (int)letter;
     return rewer;
    } 
    
    // returns the length of a character given by  UTF 8 in Byte
    short getcharart(char letter)
    {
     short rewer = -1;
     int bu = atoint(letter);
        if (bu < 192) rewer = 1;
        if ((bu >= 192) && (bu < 224)) rewer = 2;
        if ((bu >= 224) && (bu < 240)) rewer = 3;
        if (bu >= 240)rewer = 4;
     return rewer;
    }
    For some operations it is useful to know how much byes are need do show
    a character.
    Here some old charts of ASCII:
    Cout of unsigned char-0-127-jpg
    and the OLD for 128 to 255:
    Cout of unsigned char-437-jpg
    I think it don*t works without UTF8.

    Here the old sens of the characters from 0 the 32:
    Useful for old printers, RS 232:
    00 NULL, no Operation,
    01 Start of Heading SOH
    02 Start of Text STX
    03 End of Text ETX
    04 End of Transmission EOT
    05 Enquiry ENQ
    06 Acknowledge ACK
    07 Bell BEL
    08 Backspace BS
    09 HT Horizontal Tabulation
    10 Line Feed LF
    11 Vertical Tabulation VT
    12 Form Feed FF
    13 Carrige Return CR
    14 Shift out SO
    15 Shift in SI
    16 Data Link Escape DLE
    17 Device Control 1 DC1
    18 Device Control 2 DC2
    19 Device Control 3 DC3
    20 Device Control 4 DC4
    21 Negative Acknowledge
    22 Synchronous Idle SYN
    23 End of Transm.Block ETB
    24 Cancel CAN
    25 End of Medium EM
    26 Substitute SUB Character
    27 Escape ESC
    28 File Separator FS
    29 Group Separator GS
    30 Record Separator RS
    31 Unit Separator US
    32 Space SP

    It is possible when you take for example strlen() to get the length of
    a string, you get the length in byte not in characters when you use
    a mutated vowel like some german characters in a string.
    So it can be that wrong results are given when letters are encrypt
    without this.Cout of unsigned char-cppstringat-jpg
    Sorry for this example i have only a source in cpp:
    here at first main.cpp:
    Code:
    // string::at
    #include "sringat.h"
    
    
    int main ()
    {
      //char bu;
      int lge = -1, i, bulen = 0, zeize = 0, anzle = 0;
      short busta[20] = {0};
      std::string str ("Jörügüe Schönäe");
      std::string dummy = "";
      std::string sti[20] = {""};
      std::string stib[20] = {""};
      std::cout << "String: " << str << std::endl;
      std::cout << "String: 01234567891234567890123" << std::endl;
      std::cout << "String:           |          |" << std::endl;
        
      lge = str.length();
     
      
      std::cout << "String length in Bytes: " << lge << std::endl;
      
      bulen = letterlaenge(str, &sti, &zeize);
     
    
      std::cout << std::endl;
      std::cout << "String length in characters: " << bulen << "   zeize: " << zeize << std::endl;
      
      initbusta_with_1(&busta, zeize);
      
      Zaehle_Mehrfach_Zeichen_in_sti(sti, &busta, zeize);
    
      copy_sti_to_stib(sti, &stib, zeize);
    
      Streiche_doppelte_Zeichen(sti, &stib, &zeize);
      
    
      // Zeige Statistikfeld
      ShowStatistik(sti, stib, busta, zeize);
      
      std::cout <<  std::endl;
    
       for (i= 0; i < zeize; i++)     
        {
          lge = stib[i].length();    
           if (lge > 0) anzle++;
           {
            std::cout << "i=";
            if (lge == 0) std::cout << " ";
             else std::cout << stib[i];
            std::cout << "   l=" << lge << std::endl;
           }
        }
        std::cout << "number of different characters: " << anzle << std::endl << std::endl;
     
     return EXIT_SUCCESS;
    }
    now stringat.h
    Code:
    #ifndef SRINGAT_INC_
    #define SRINGAT_INC 1
    
    #include <iostream>
    #include <string>
    #include <iomanip>
    #include <cstdlib>
    
    int atoint(char letter);
    short getcharart(char letter);
    int letterlaenge(std::string str, std::string (*sti)[20], int *zeichze);
    void ShowStatistik(std::string sti[20], std::string stib[20],  short busta[20], int zeize);
    void initbusta_with_1(short (*busta)[20], int zeize);
    void copy_sti_to_stib(std::string sti[20], std::string (*stib)[20], int zeize);
    void Zaehle_Mehrfach_Zeichen_in_sti(std::string sti[20], short (*busta)[20], int zeize);
    void Streiche_doppelte_Zeichen(std::string sti[20], std::string (*stib)[20], int *zeize);
    
    #endif
    at last stringat.cpp
    Code:
    #include "sringat.h"
    
    //converts signed char to int
    int atoint(char letter)
    {
     int rewer;
     if ( letter < 0)
      rewer = letter + 256;
       else rewer = (int)letter;
     return rewer;
    } 
    
    
    
    // returns by UTF 8 laenth of characters in Byte
    short getcharart(char letter)
    {
     short rewer = -1;
     int bu = atoint(letter);
        if (bu < 192) rewer = 1;
        if ((bu >= 192) && (bu < 224)) rewer = 2;
        if ((bu >= 224) && (bu < 240)) rewer = 3;
        if (bu >= 240)rewer = 4;
     return rewer;
    }
    
    // length of string
    int letterlaenge(std::string str, std::string (*sti)[20], int *zeichze)
    { 
      std::string dummy = "";
      int i, bu = 0, sl = 1, lge = -1, bulen = 0, zeize = 0;
      lge = str.length();
    
      bulen = lge;
    
     for (i = 0; i < lge; ++i)
      {
       bu = str[i];
       sl = getcharart(bu);
       dummy = str.substr(i,sl); 
       if(sl > 1 ) i += (sl - 1);
       bulen -= (sl - 1);
       (*sti)[zeize] = dummy;
       zeize++;
       //std::cout << str.at(i) << " =  " << int atoint(str.at(i)) << std::endl;
       std::cout << dummy << " = " << std::setw(3) << bu << "   laenge: " << sl << "  =  " << atoint(bu) << std::endl;
      }
     
     *zeichze = zeize;
     return bulen;
    } 
    
    void ShowStatistik(std::string sti[20], std::string stib[20],  short busta[20], int zeize)
    {
     int i;
      std::cout << "Statistic  zeize=" << zeize << std::endl;
      for (i = 0; i < zeize; ++i)
       {
        std::cout << "sti[" << std::setw(2) << std::setfill(' ') << i << "] = " << sti[i]; 
        std::cout << "   stib[" << std::setw(2) << std::setfill(' ') << i << "] = " << std::setw(1) << std::setfill(' ') << stib[i];
        std::cout << "    number: " << busta[i] << std::endl;
       }    
     std::cout << "Statistic End" << std::endl;
    }
    
    
    void initbusta_with_1(short (*busta)[20], int zeize)
    {
      for (int i = 0; i < zeize; i++) (*busta)[i] = 1;   
    }
    
    void copy_sti_to_stib(std::string sti[20], std::string (*stib)[20], int zeize)
    { 
     for (int i = 0; i < zeize; i++)
      (*stib)[i] = sti[i];
    }
    
    // gets characters where are more as on time in string
    void Zaehle_Mehrfach_Zeichen_in_sti(std::string sti[20], short (*busta)[20], int zeize) 
    {
     for (int i = 0; i < zeize; i++)
      {
       for (int j = i + 1; j < zeize; j++)     
        if (sti[i].compare(sti[j]) == 0) (*busta)[i]++;
      }   
    }
    
    // deletes charactes where ar more as one time in string
    void Streiche_doppelte_Zeichen(std::string sti[20], std::string (*stib)[20], int *zeize)
    {
      for (int i = 0; i < *zeize; i++)
      {
       for (int j = i + 1; j < *zeize; j++)     
        if (sti[i].compare(sti[j]) == 0) (*stib)[j] = "";
      } 
    }
    Sorry, exaple is coded in german language, some details i'd tranlated in
    english the last 5 minutes. But i hope it is useful for you.
    Attached Images Attached Images Cout of unsigned char-0-127-bmp 

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How covert unsigned char[4] to unsigned integer?
    By barracuda in forum C Programming
    Replies: 110
    Last Post: 02-23-2015, 04:00 AM
  2. Unsigned char array to unsigned char?
    By Kishintai in forum C Programming
    Replies: 16
    Last Post: 04-26-2013, 01:37 PM
  3. Replies: 4
    Last Post: 07-24-2012, 10:41 AM
  4. Replies: 2
    Last Post: 10-06-2009, 09:37 AM
  5. cast unsigned char* to (the default) signed char*
    By Mario F. in forum C++ Programming
    Replies: 24
    Last Post: 07-27-2007, 10:41 AM

Tags for this Thread