3

All, I'm still learning C++ but I have an issue in a project I'm tinkering with that I'm curious about. I've noticed that when I try to print the contents of a string that is a member of a class, I get the memory address instead of the contents. I understand that this is because the item is a pointer, but what I"m confused about is that I am using the -> operator to deference it.

Why can I evaluate the class member in an if statement using the -> operator to dereference it but when printing to a file string in the same manner I get the memory address instead?

An example is below:

Lets say I have a class called pClass with a member called m_strEmployeeName. As a side note (I don't know if it matters), the m_strEmployeeName value is CString rather than std::string, so there could be some unknown conversion issue possibly as well.

If I used the following simple code, I get a memory address.

std::ofstream file("testfile.text");
file << pClass->m_strEmployeeName;
file.close();

I get the same behavior with the following dereferencing method (which I would expect since -> is the same thing).

std::ofstream file("testfile.text");
file << (*pClass).m_strEmployeeName;
file.close();

Any idea on what I'm doing wrong?

crashmstr
  • 28,043
  • 9
  • 61
  • 79
sallou
  • 99
  • 9
  • Problem is `CString` not how you refer that member. Just create a variable of type `CString` and try to print it. – Slava Nov 17 '15 at 19:36
  • Just to make sure, you know you are dereferencing `pClass`, not `m_strEmployeeName`, right? Cause in the sentence `I understand that this is because the item is a pointer, but what I"m confused about is that I am using the -> operator to deference it.` you seem to imply otherwise. – JSQuareD Nov 17 '15 at 19:37
  • 1
    I've added the `MFC` tag, since you are using `CString`. `CString` is not part of the standard C++ library and the iostreams knows nothing of it (hence the address being printed). ebyrob's answer will work if you need to stick with `CString`. – crashmstr Nov 17 '15 at 19:44
  • Check the docs for `CString` for the correct way to use it. – David Schwartz Nov 17 '15 at 22:37

2 Answers2

3

It is because your CString class is actualy CStringW class wich contain wchar_t strings so std::ofstream not contain operator >> overload that support wchar_t* strings. To print CStringW class objects you may use this type of stream std::wofstream it recognize wchar_t* strings properly and output will be right.

std::wofstream file("testfile.text");
file << pClass->m_strEmployeeName;
file.close();

You may also create your program in multibyte character support. It can be specified in your project settings. But I suggest you to stay with UNICODE.

Mykola
  • 3,343
  • 6
  • 23
  • 39
1

Try casting CString to a char pointer:

file << (LPCTSTR)pClass->m_strEmployeeName;

see: How to convert CString and ::std::string ::std::wstring to each other?

Note: This will only work if you have TCHAR defined as 8 bits. If you're using 16-bit UNICODE TCHAR, you'd have one more conversion.

Here is one way of doing the TCHAR conversion:

char c_str[1000];
size_t ret;    
wcstombs_s(
   &ret,
   c_str,
   sizeof(c_str),
   (LPCTSTR)pClass->m_strEmployeeName,
   pClass->m_strEmployeeName.GetLength()
);

std::ofstream file("testfile.text");
file << c_str;
file.close();

Useful if you need 8-bit ASCII file but have a UNICODE CString to work with.

Community
  • 1
  • 1
ebyrob
  • 667
  • 7
  • 24
  • 1
    I would recommend using `std::string` instead rather than convert. – Slava Nov 17 '15 at 19:40
  • 1
    @Slava agreed, but in case there's a good reason to use `CString` this will work. – ebyrob Nov 17 '15 at 19:41
  • Output will remain same, because `UNICODE` is defined so `LPCTSTR` will be `LPCWSTR` and it is `const wchar_t*`, `T` letter means `TCHAR` and WHEN `UNICODE` is defined it will be `WCHAR` alse it is `CHAR`. – Mykola Nov 17 '15 at 19:52