1

I have something pretty simple to do, I am trying to prompt the user for character input & save that character onto a string. Then I print that whole string.

The program is for windows but I want the program to work for both ASCII & Unicode which is why I user TCHAR, & wstring.

My Problem: I am unable to add the character(that the user inputs) onto a wstring. It just wont be stored in that variable. Why?

My simple code:

#include <windows.h>
#include <tchar.h>
#include <conio.h>  
#include <stdio.h>  
#include <string>
#include <iostream>

using namespace std;

int main()
{
    // I am using wstring for unicode compatibility but in Windows(MSDN) is there a general
    // string variable? You know how there is char, wchar & then TCHAR(which is a general variable
    // for both ASCII & unicode). Is there a TSTRING or something?
    wstring chStr = L"abc";  
    TCHAR ch      = L'a';

    while ( ch != '!' )
    {
          printf("Enter a character: ");
          ch = getch();
          chStr += ch; // the string never takes on a char it always remains as "a"
          printf("\nThe characters entered so far are: %s \n", chStr.c_str()); 
    }

    system("PAUSE");
    return 0;   
}
Mack
  • 11
  • 2
  • Why do you need ASCII support? Are you still using Windows 3? – Bo Persson Jul 10 '11 at 06:11
  • There is no `std::tstring` . You can do this though: `typedef std::basic_string tstring` – Nubcase Jul 10 '11 at 06:21
  • `TCHAR` is a typedef which could be either `char` or `wchar_t`, so you have to account for that somehow. Here is a [little rant](http://stackoverflow.com/questions/6300804/wchars-encodings-standards-and-portability) of mine on wide char generalities. – Kerrek SB Jul 10 '11 at 12:28
  • You need to use %ls in your printf() statement to display Unicode strings. %s will only display the 1st character in a wide string, the 2nd byte is apt to be zero so acts as the string terminator. Do avoid mixing string types. – Hans Passant Jul 10 '11 at 13:46

3 Answers3

1

You can use tchar* input and then

 wstring chStr = L"abc";  
 std::wstring s(input)
 chStr += s;
Alok Save
  • 202,538
  • 53
  • 430
  • 533
0

http://linux.about.com/library/cmd/blcmdl3_wprintf.htm

says you need to use %ls not %s with wprintf()

:)

you see, it's reading the wide string as a char string with one char and a null.

marinara
  • 538
  • 1
  • 5
  • 10
0

Your test isn't showing what you think it is showing.

The printf function expects ASCII string parameters for the %sformat specification. The UNICODE representation for the letter a is 0x0061 which is stored in memory as 0x61, 0x00 (because we're dealing with a little-endian system). Since printf is interpreting the memory as an ASCII string, 0x61, 0x00 looks to be a null terminated string that is one character long, so that's what you get printed.

It doesn't really make sense to use TCHAR anymore. The TCHAR type is either WCHAR or char depending on whether the macro UNICODE is defined or not. TCHAR is useful in cases where you want to write code that can be compiled twice - once for ASCII and once for UNICODE. For example when you wanted to write code that could be compiled to run efficiently on ASCII platforms (like Windows 95) and compiled again to run efficiently on UNICODE platforms (like Windows XP).

Now that all current Windows operating systems are natively UNICODE, there's not much use for TCHAR and some risk to using it.

For example, your code TCHAR ch = L'a'; is valid when compiling for UNICODE because TCHAR is defined to be WCHAR in that case. But, when compiling for non UNICODE, TCHAR is defined to be char and assigning a Unicode character like L'a' to a char variable doesn't really make sense. You won't necessarily get a syntax error, but you won't necessarily get the code you expect either.

Note Where I used "ASCII" above I probably should really have said "multi-byte character set" or "non-UNICODE character set" since not all non-UNICODE character sets are ASCII.

Frank Boyne
  • 4,400
  • 23
  • 30