But the standard is a piece of shit. Anything with a name resembling a character should be at fucking least 21 bits, and the ONLY character set which it should ever support should be ISO/10646 UCS. Then strings should be abstracted so you don't poke your nose (overriding [] as necessary) and they should use an implementation-defined Unicode Transformation Format out of the three possible UTF-8, UTF-16 and UTF-32, with full Unicode semantics as defined in Unicode 5.0 and no character set/encoding conversions AT FUCKING ALL. Then, when you want to read/write strings from/to a file/terminale/etc., you either use the Unicode Transformation Format used by the stream (one of UTF-8, UTF-16, or UTF-32, specified when creating it), or you can call the function __WARNING__SHIT_COMING_convert_character_set_yes_I_really_want_to_do_this_yes_I_know_I_shouldnt(str, other_legacy_goddamned_piece_of_shit_charset, FOR_REAL | YES_I_AM_A_MORON_FOR_NOT_USING_UNICODE). Of course, for binary files and sockets, you should use byte arrays, whose type should be byte or signed byte, and you'd have a function similar to the one I described for byte array to string conversion.
That's how things should be done. Anything that's not Unicode should be filtered through kill_this_shit(WITH_FIRE).