Solved

Just trying to 'cout' a CString

Posted on 2006-06-15
19
2,529 Views
Last Modified: 2013-12-14
Excuse the stupidity of this question, but its been bugging me:

<<CODE>>
   CString blah("HELLO");
   cout << blah << endl;
   printf ("%s", blah);
<</CODE>>

In the 'cout' case it seems to be printing out the mem address of 'blah', in the 'printf' case it prints out only the first letter of 'blah'  ("H").  What the heck is going on here.  Any help is appreciated....Im sure this is an easy one, I'm just new to CStrings.  Thanks
0
Comment
Question by:Pheonix911
  • 6
  • 5
  • 5
  • +2
19 Comments
 
LVL 4

Expert Comment

by:MikeGeig
ID: 16912808
Are you attached to the CString class? I would recommend using the std::string class instead. string is the newer more c++ based version of the c based CString.

the code you want would looke something like

string blah = "hello";
cout << blah;
0
 
LVL 4

Expert Comment

by:MikeGeig
ID: 16912829
i forgot

printf(%s, blah);

but thats not exactly vital since it didn;t change between to two. Also, the new string.h is an awesome class because it contains many new methods to add easy use to your programs.
0
 

Author Comment

by:Pheonix911
ID: 16912971
ok...but saying I wanted to use CString...your saying I can't???
0
 
LVL 30

Accepted Solution

by:
Axter earned 100 total points
ID: 16913108
>>ok...but saying I wanted to use CString...your saying I can't???

You can use CString, but you should cast it to the LPCTSTR operator.

cout << (LPCTSTR)blah << endl;

If you don't like cast, you can do the following:
cout << blah.operator LPCTSTR() << endl;
0
 
LVL 86

Expert Comment

by:jkr
ID: 16913111
Try

cout << (LPCTSTR) blah << endl;

which will call 'CString::operator LPCTSTR()'. This way, you'll get the contents as a 'char*', wich works with 'cout'.
0
 
LVL 30

Expert Comment

by:Axter
ID: 16913155
By the way, my personal preference is CString over std::string.

Most hard-core C++ programmers prefer std::string over CString.

There's nothing wrong with mixing CString and STL code.
For example, I prefer std::vector over CArray, so I use std::vector<CString> instead of CStringArray.

You'll also find CString to be more efficient then the std::string implementation that comes with VC++.  At least I know this to be true with VC++6.0.  I'm not sure if they've improved the std::string implementation in 7.1 or 8.0
0
 
LVL 30

Expert Comment

by:Axter
ID: 16913209
MikeGeig,
>> Also, the new string.h is an awesome class because it contains many new methods to add easy use to your programs.

There is no new string.h header for C++.
The std::string class is declared in the <string> header.

The official C++ standard has a string.h header which is the C string.h header, and does not include std::string declaration.

0
 
LVL 4

Expert Comment

by:MikeGeig
ID: 16913328
axter, that was a mistake on my part, after reading it, i did not intend it the way it seems. I just meant the string class in general.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 16913477
Here's a fix for ostream.

--------8<--------
// Compile with /MT /EHsc

#include "afx.h"
#include <iostream>

#if 1200 <= _MSC_VER /* For the sake of VC 6. VC 7 doesn't need this */
inline std::ostream& operator<<(std::ostream& os,const CString& str)
{
      return os << static_cast<LPCTSTR>(str);
}
#endif


int main()
{
      CString greeting = "Hello, world";
      std::cout << greeting << std::endl;
      return 0;
}
--------8<--------
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 30

Expert Comment

by:Axter
ID: 16913800
>>inline std::ostream& operator<<(std::ostream& os,const CString& str)

Good idea, but I would not use the static_cast, and instead call the operator directly.

inline std::ostream& operator<<(std::ostream& os,const CString& str)
{
     return os << str.operator LPCTSTR();
}
0
 

Author Comment

by:Pheonix911
ID: 16919533
ok...so it sounds like I should be using std::string.  But the reason I was using CString was to ease my casting from wchar_t.  How can I convert wchar_t to std::string?
0
 
LVL 4

Expert Comment

by:MikeGeig
ID: 16919552
0
 
LVL 4

Expert Comment

by:MikeGeig
ID: 16919562
0
 
LVL 30

Expert Comment

by:Axter
ID: 16920001
>>ok...so it sounds like I should be using std::string.  But the reason I was using CString was to ease my casting from wchar_t.  How can I convert wchar_t to std::string?

Beaware that a disadvantage of using std::string over CString is that your code will not work implicitly with API functions that take TCHAR.
So if you ever decide to change your project from ANSI to UNICODE or from UNICODE to ANSI, you're going to have to make a lot of code changes.
Another disadvantage, is that the VC++ std::string is slower then CString.
Also, std::string doesn't work implicitly with printf type functions like CString does, so you'll have to use string::c_str function when using it with printf, or any function that takes a C-string pointer.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 16920247
> How can I convert wchar_t to std::string?

Use std::wstring, std::wcout, std::wcin, std::wfstream etc, if you want to use wide characters predominantly in your application. There are wchar_t counterparts for all of the standard library char classes.
0
 

Author Comment

by:Pheonix911
ID: 16922373
    So I've modified my code like so:

<<CODE>>
  string blah = "hello";
  cout << (LPCTSTR)blah;
<</CODE>>

     And heres the weird thing.  In VS .Net 2k5 I get the mem location of 'blah'.  However in VS .Net 2003 I get the correct output 'hello'.  Whoever gets this, gets the points :o)  As this as been killing be for far too long.
Thanks
0
 

Author Comment

by:Pheonix911
ID: 16922408
That is supposed to be:

<<CODE>>
  CString blah = "hello";
  cout << (LPCTSTR)blah;
<</CODE>>

sorry
0
 
LVL 30

Expert Comment

by:Axter
ID: 16922531
Try using the operator function as I previously posted.
cout << blah.operator LPCTSTR() << endl;
0
 

Author Comment

by:Pheonix911
ID: 16923060
The answer was actually that VS.Net 2005 is set, by default to unicode...where CStrings are multibyte's ... changing this in the project properties resolved the issue....although I still needed to type case, so giving points to Axter...thanks
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Programmer's Notepad is, one of the best free text editing tools available, simply because the developers appear to have second-guessed every weird problem or issue a programmer is likely to run into. One of these problems is selecting and deleti…
Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now