Convert CString to String C++

I  an example of concerting a CString to a String on printeed oage 11 of the Code Projectt article The Complete Guide to C++ Strings, Pat II - String Wrapper classes.
Here is my code

// TBConvertCString.cpp : Defines the entry point for the console application.
// A testbed to try the conversion fron CString to normal standard strings

#include "stdafx.h"
#include <cstring>
#include  <atlstr.h>
using namespace std;

int main()
{
      CString m_name = _T("test string");
      String* s2(m_name);
      return 0;
}


When I try ti build this code I get the following errors

      1      IntelliSense: identifier "String" is undefined      c:\CPP2013\TBConvertCString\TBConvertCString\TBConvertCString.cpp      12
      2      IntelliSense: identifier "s2" is undefined      c:\CPP2013\TBConvertCString\TBConvertCString\TBConvertCString.cpp      12

I am now completely lost here
HELP
Dave ShieldsAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Karrtik IyerSoftware ArchitectCommented:
Two issues I could possibly see :
1) string class starts with small 's' and not big 'S'
2) header file for string class is missing I think, you need to include #include <string>
Karrtik IyerSoftware ArchitectCommented:
I think the part of tutorial you are reading is about converting CString to a managed. NET String, is that what you want? My previous answer was with thought that you wanted to convert it to a C++ string class.
If you want to convert it managed. Net string then make sure have enabled CLR for the C++ project, in general settings of the project, right click properties.
If you are looking for converting CString to c++ string, then here are two ways :
1)For unicode strings :
CString str = L"Test";
std::wstring ws(str);
std::string s;
 
s.assign(ws.begin(), ws.end());

2) CString m_Name;
CT2CA pszName(m_Name);
std::string m_NameStd(pszName);
Karrtik IyerSoftware ArchitectCommented:
If your intention is to convert CString to Managed .NET System::String then here are the steps.
1> Enable CLR for your C++ project, please see attached picture CLR_support.png. (select /clr option: Common Language Runtime support).
2> Add reference to System.Core dll (.NET) component, by selecting references (right click on project) and Add new reference, and select .NET tab and in that select System.Core component. (see attached picture
3> Then in your code add code
using namespace System;

Open in new window

below the line using namespace std;
4> And write below code: (this shall print the .NET string to console)
	CString m_name = _T("test string");
	String^ s2= gcnew String(m_name); //Create a .NET string using gcnew which indicates that garbage collector shall take care of managing its resources/deleting the resource
	Console::WriteLine(s2);

Open in new window

CLR_Support.png
System_Core.png
JavaScript Best Practices

Save hours in development time and avoid common mistakes by learning the best practices to use for JavaScript.

Dave ShieldsAuthor Commented:
Hi,
I am using Visual C++ 2013, and ALL of the documentation and examples use String to describe the String class.  I think this is right.

When I add "using namespace System; , the compiler complains that 'System' is NOT a namespace name.

I am not trying to make NET variables; I am trying to finish a short test-bed program.
Karrtik IyerSoftware ArchitectCommented:
Did you add the reference to System.Core as I attached in the screenshot in my previous comment?
Did you enable CLR?
Else it shall not work, in pure C++ (standard library) there is no string class starting with big 'S'.
I checked the code project tutorial you are referring to and your example belongs to the section of CLR and VC7 classes. See below, this section is to demonstrate how to convert a CString to managed .NET string.
In visual studio, you can have pure C++ code inter mingled with CLR code if CLR is enabled, which is what the below section is talking about.

CLR and VC 7 classes

System::String is the .NET class for handling strings. Internally, a String object holds an immutable sequence of characters. Any String method that supposedly manipulates the String object actually returns a new String object, because the original String is immutable. A peculiarity of Strings is that if you have more than one String containing the same series, of characters all of them actually refer the same object. The Managed Extensions to C++ have a new string literal prefix S, which is used to represent a managed string literal.

Hide   Copy Code
// Constructing
String* ms = S"This is a nice managed string";
Karrtik IyerSoftware ArchitectCommented:
Hi Dave, to explain how this works clearly to you, I have create and attached a VS 2013 C++ console application project with below code. I have added comments on each line to explain what it does.
Please let me know if this helps. Please rename the .txt file to .vcxproj
Thanks,
Karrtik
	CString somename = L"This string is somename.";//This is a unicode string since in project settings we have set character set as use unicode character set --> General settings

	//Test case1: Convert unicode CString to standard C++ string	
	std::wstring ws(somename);//wstring is the unicode couterpart of std::string in C++ standard library and since CString is containing unicode, it can be directly assigned to ws.
	wcout << L"1: " << ws << endl;//Directly printing unicode string
	std::string s;
	s.assign(ws.begin(), ws.end());//Here we are assigning a unicode wstring to string, hence using the being and end iterators since they cannot be directly converted to each other, ideally we should not do this since unicode characters (if some non English language like Japanese) might get lost/corrupted in this conversion, we should directly use wstring instead.
	cout << "1_1: "<< s << endl;

	//Test case2: Convert unicode CString to standard C++ string another method 	
	CT2CA pszName(somename);
	std::string m_NameStd(pszName);
	cout << "2: " << m_NameStd << endl;

	//Test case 3: Convert CString to managed .NET string, This shall only get compiled if CLR is enabled in general settings for this project and system.CORE reference is added for the project.
	String^ s2 = gcnew String(somename); //Create a .NET string using gcnew which indicates that garbage collector shall take care of managing its resources/deleting the resource
	Console::WriteLine(L"3: " + s2);

Open in new window

main.cpp
StringConverstionTest.txt
sarabandeCommented:
ALL of the documentation and examples use String to describe the String class.  I think this is right.
both assumptions are wrong for a default mfc project (or a c++ win32 console project using mfc).

as Karrtik has explained a few times, there are two different compilers involved, both named c++ by ms, what may cause the confusions. C++, also called "regular C++" or "unmanaged C++" or "normal C++" (all these names are ugly and not useful) is a language created by Bjarne Stroustrup, which is a superset of the C language and adds a complete set of object-oriented extensions to the C language. you could use c code in a c++ program but not vice versa (if using any of the extensions like classes). c++ has got an own standard at 1998 and following standards in younger times.  

"Managed C++" also called C++/CLR or C++.NET is a new language with c++ syntax which actually has little in common with c++. ms offers a mixed-mode and named it IJW (it just works) but actually i didn't have seen working projects written in mixed mode and since you have to consider a bunch of rules to get it working, i strongly recommend against such coding, especially for a beginner.

a beginner should decide for c++ or for c# if they want to go the .NET way. managed c++ and c# create the same intermediate code, but c# is a newly designed language and not a hybrid like managed c++. the only advantage of managed c++ to be able to use existing code more easily could be achieved to either port exist c++ code to c# or to using (pure) c++ dll's from c#.

FYI: the article you mentioned tries to cover all kind of string types in the c, c++, mfc, managed c++, com world. im my opinion you picked one of the least practical combinations described in this article:  mfc + managed c++.  mfc, is a class library which adds gui classes to c++. these gui classes are based on pure winapi (a c interface). mfc also has a few container classes where CString is the best one. unfortunately, CString is either based on wide characters (UTF-16) or on ANSI characters (called multi-byte by MS though based on - single - char type) and you can't switch between these but but only decide for one or the other. 'String' class from .NET  always is UTF-16 and badly supports ANSI or other character sets (for example UTF-8, full UNICODE).

Sara
Dave ShieldsAuthor Commented:
You have been a big help in the past.  I am using Visual Studio C++ 2013 only.  I am still working on the project that I was working on then.  Here is the whole story.  The project has one interface with the user, a fill-in-the-blanks dialog with only 2 options.  The dialog has been finished and works well, but it uses CString as it's string type.

The next step is to take that string and many other strings to perform parsing operations to extract information from the text.  The text is in HTML which I am familiar with.  VC++ has a String class which includes extensive functions which I can use to parse the text.  I have no special interest in writing .NET code, and would prefer to make everything as simple as possible.

I have only the one compiler which I am committed to.  Sincerely, how would you suggest I proceed.  Once again, many thanks for your past help.
Dave ShieldsAuthor Commented:
You have been a big help in the past.  I am using Visual Studio C++ 2013 only.  I am still working on the project that I was working on then.  Here is the whole story.  The project has one interface with the user, a fill-in-the-blanks dialog with only 2 options.  The dialog has been finished and works well, but it uses CString as it's string type.

The next step is to take that string and many other strings to perform parsing operations to extract information from the text.  The text is in HTML which I am familiar with.  VC++ has a String class which includes extensive functions which I can use to parse the text.  I have no special interest in writing .NET code, and would prefer to make everything as simple as possible.

I have only the one compiler which I am committed to.  Sincerely, how would you suggest I proceed.  Once again, many thanks for your past help.
sarabandeCommented:
as told CString is a very comfortable string class. in most of my projects i am using an new string  class of my own, often by using the same interface as with CString (such to be able to use the same code and only have to exchange the string type). but the better is the enemy of the good: hence, my string classes also offer many additional parsing functions (for example a tokenizer, or stringToArray and ArrayToString), and above all additional streaming functions. so i can do like

MyString str("What ever ");
int n = 2;
double price = 123.456;
str << "you want from " << MyString("me|him|her").GetNthToken(n, "|") << " will cost " << price << " $";
CString m_strOutput = (const char *)str;
UpdateData(FALSE); // output to screen

Open in new window


though my string class has many functions same as CString it is internally based on std::string which is string class of c++ standard. std::string actually is std::basic_string<char> and is suitable for ANSI and/or UTF-8. for UTF-16 one would have to use std::wstring where the template type is wchar_t. however, it is again a difficult decision to go the wide character way, especially if it is rather a rare case that you have to display or handle unicode characters. nevertheless with your own class you have the chance to support any character set needed by providing the necessary constructors, assignment, streaming and cast operators.

The text is in HTML which I am familiar with.
 
if UTF-16 is the only character set you were using in HTML, .NET and its String class could be a good decision. as told, i would go for c# rather than managed c++ and would port the mfc dialog to a windows form dialog (what is not so difficult since the concepts are still the same, only the names have changed).

if the HTML could contain UTF-8 or ANSI as well, you also could use c# to firstly convert all texts to UTF-16 wide strings. however, that might be not so simple, especially if you have to convert it back to the original character set after change.

if you can go with ANSI and have not enough time for your own string class, i would trust on CString and add some functions from other string classes which you need. none of these implementations will last more than a few hours, granted that you know what you want and where you could simplify the requirements to fit your purposes.

Sara
Karrtik IyerSoftware ArchitectCommented:
Hi Dave and Sara, Can I suggest that we close this question since the direction we are heading and what question was raised initially are totally different? Instead would it be better if Dave shares some of his Dialog code as sample VC++ project in a new question and show us what is he trying to do and what he wants to achieve?
It would help us to solve his problem faster if he can share similar (if same is not shareable) code with a sample project. This is my sincere suggestion.
Thanks,
Karrtik
Dave ShieldsAuthor Commented:
Hi Karrrtik and Sara'
The only purpose of the dialog is to get a string from the user.  This has been done, and the the dialog returns a CString.  My problem now is to be able to use and parse that CString.  CString itself has very primitive parsing functions.

When I searched the help section of Visual Studio c++ for string it only returned the String class, which has a rich selection of built-in parsing functions.  Help did not mention that there was a string class.  Sara has suggested std::string which also has  a rich selection of parsing functions.   If all the complications of .NET can be avoided by the string class, then my only hurdle would be to convert the CString to a string.  Back in 2007 I wrote a parser which could work on HTML code.

To me, the creation of my own string class seems a daunting task.  I suppose I could inherit from string, but it already seems to have all I would need.  If I knew that the string class would work I could progress starting now.

Dave
Dave ShieldsAuthor Commented:
Hi Karrrtik and Sara'
The only purpose of the dialog is to get a string from the user.  This has been done, and the the dialog returns a CString.  My problem now is to be able to use and parse that CString.  CString itself has very primitive parsing functions.

When I searched the help section of Visual Studio c++ for string it only returned the String class, which has a rich selection of built-in parsing functions.  Help did not mention that there was a string class.  Sara has suggested std::string which also has  a rich selection of parsing functions.   If all the complications of .NET can be avoided by the string class, then my only hurdle would be to convert the CString to a string.  Back in 2007 I wrote a parser which could work on HTML code.

To me, the creation of my own string class seems a daunting task.  I suppose I could inherit from string, but it already seems to have all I would need.  If I knew that the string class would work I could progress starting now.

Dave
Karrtik IyerSoftware ArchitectCommented:
Hi Dave, I have worked with both cstring and string extensively. Both have enough functionalities built in or which can be added easily to perform any kind of parsing that I normally needed in all these years. In my current project I recently built my own small html parser (to parse html tags) and apply them on the string given. This was entirely built using wstring which is c++ counterpart for unicode strings. So my suggestion is that there is no need to convert it to String (.net).
And converting CString to wstring is pretty straightforward, you can see my previous example on it. So I suggest that you proceed with the same.
Let us know if you need any help in parsing.
Thanks,
Karrtik
sarabandeCommented:
Dave, i don't share your opinion that CString has only primitive parsing functions while std::string has a rich selection of those. both classes have advantages and disadvantages and the easier class is CString especially since it has a built-in cast operator such that it could be used instead a const TCHAR * (or LPCTSTR).

because of this when TCHAR is char type you simply can convert a CString to a std::string by

CString cstr = "....";
std::string str = (const char *)cstr;

Open in new window


or when TCHAR = wchar_t type by

CString cstr = L"....";
std::wstring wstr = (const wchar_t *)cstr;

Open in new window


note, instead of std::string and std::wstring you also could use std::basic_string<TCHAR>.

for the other direction you have to use c_str member function of basic_string since there is no cast operator defined.

if you have mixed char and wchar_t strings, you have to use "UNICODE" character set in mfc such that TCHAR turns to wide character type. the std::string then must be converted to std::wstring for example by using mbstowcs function or by using _bstr_t string class for converting.

Sara
Dave ShieldsAuthor Commented:
Hi Karrtik and Sara;
Sara, you know that I listen to you and reread your comments several times before acting.   One complication that I haven't mentioned is that the program will have to do more than read a web page; it will have to read ALL the pages in the website.  One website that I was managing back in 2000 had 1,200 pages.  I think that volume of parsing would limit me to C++ just for reasons of speed.

In the past to remember and organize all error messages, I used the StringCollection class.  By error I mean HTML coding errors.  One difficulty with StringCollection is that it does not work with CString or std::string.  

That leaves String.  I found out the there is a quirk in MS documentation for C++ 2013.  When one searches help for"string",  it returns the String class and way down the list it mentions std::string.
sarabandeCommented:
a container comparable to StringCollection is std::vector<std::string>. if you want to keep the pages still to be together you might use std::vector < std::vector < std::string > > where the outer vector handles pages and the strings perhaps are lines. the advantage of such an individual container is that you could add an index like { 10, 20, 30 } (a struct with 3 integers, triple_int) for any interesting string parts you want to evaluate.  { 10, 20, 30 }  would mean page 10, line 20 and character 30. when reading the pages you could build such an index for errors and use a std::map<int, std::vector<triple_int> >  which could be filled while reading the pages to quickly spot any error code in the contents.

alternatively, you may read all text into one CString or one std::string. both could have a maximum of 2 gb. contiguous memory of such size only would be available in a 64-bit program. but if we assume that 1 page has a maximum of 1000 characters the total size is only 1 mb what shouldn't be an issue even for 32-bit programs. both CString::Find or std::string::find are fast enough and same as for the page-line container explained above you may create an index which points to interesting parts of the text.

Sara
Karrtik IyerSoftware ArchitectCommented:
In addition to what Sara has mentioned in her last comment, for CString collection, vc++ and Microsoft have provided different collection classes support such as CList, CArray and CMap. Please see example below on how to use it and when to use what.
http://www.ucancode.net/Free-VC-Draw-Print-gdi-example-tutorial/MFC-CList-CArray-CMap-VC-Source-Code.htm#_UsingCMap
Dave ShieldsAuthor Commented:
I think Karrtik has raised a valid point; that the original question has been answered.  I am inclined to split the points if you agree.  Sara, you have raised a really interesting possibility which I will research tomorrow.  It opens up the project so that I can select a string type based on its merits rather than a criterion of a secondary function.  Thanks again.
Karrtik IyerSoftware ArchitectCommented:
Hi Dave and Sara,
I have two view points regarding split of points. Pardon me if you think it is unjustified.
1> If we consider the original question from Dave which was regarding compilation issues using String (managed) class, I think my response and sample project resolves this issue. So splitting the points in this case does not seem to be correct in my mind.
2> If we consider the question to be more of which is the appropriate data type to achieve the html parsing and formatting, whether to convert CString to String , or any other data type like std::string or std::wstring, which kind of came out during later discussions on this question, I understand and agree that the points should be split.
Thanks and regards,
Karrtik
sarabandeCommented:
Karrtik, i don't care so much about points and generally are sidestepping discussions about points since in my opinion only the Author of a question can judge how much answers have helped.

beside of that you are right that you answered the original question and that my comments were an addition to yours and answers to questions which were following the original question.

Sara
sarabandeCommented:
Dave, for the PAQ database it is important that the accepted comment is an answer to the original question regardless of the amount on points. because of that even an own comment could be the accepted solution (0 points).

if a thread has arised new questions you may consider to ask them in a new thread and add mutual links to both. you can do that to any time even if the discussion already had took place in the first question. you would then begin the new thread with a summary and finally ask a new question with new points where you are again free to decide at your will.

Sara

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sarabandeCommented:
Dave, the accepted comment should be Kartik's answer http://www.experts-exchange.com/questions/28817659/Convert-CString-to-String-C.html#a41203365 which is an answer to the original question.

both my two recent comments shouldn't get any points, since they are no answers.

Sara
Dave ShieldsAuthor Commented:
Sara, you are really the best.  However, I have already split the points yesterday.  I'm not sure how that went, because I don't get feedback.  By putting answers in context and giving me enough information to stimulate my understanding, you provide a very profound service.

New question
I have lost the help files on my compiler for std::string.  Is there any way I can restablish these from Microsoft?  TTYL
sarabandeCommented:
in visual studio editor F1 on 'std::string' term should show up msdn help.

if not (or if msdn help is not configured in visual studio), you can go directly to msdn help at
https://msdn.microsoft.com/en-us , click at the search button in the title bar, and search for basic_string (which is the template class for both std::string and std::wstring).

a direct link to basic_string help is https://msdn.microsoft.com/en-us/library/syxtdd4f.aspx

Sara
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual C++.NET

From novice to tech pro — start learning today.