CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 4 1234 LastLast
Results 1 to 15 of 53
  1. #1
    Join Date
    Nov 2003
    Posts
    55

    CString -vs- std:string ?

    A couple of questions re CString -vs- std::string ...

    1. What are the pros and cons of using CString -vs- std::string ?
    2. If you were going to pick one to be your primary string type til the end of time, which would you pick?

    Thanks

  2. #2
    Join Date
    Apr 2004
    Location
    Canada
    Posts
    1,342

    Re: CString -vs- std:string ?

    std::string is part of the C++ Standard so, IMO, that is the best choice

  3. #3
    Join Date
    May 2004
    Location
    Norway
    Posts
    655

    Re: CString -vs- std:string ?

    And please do a search.. There have been oodles of threads about this in the past.
    Insert entertaining phrase here

  4. #4
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    Re: CString -vs- std:string ?

    Quote Originally Posted by rlewkov
    A couple of questions re CString -vs- std::string ...

    1. What are the pros and cons of using CString -vs- std::string ?
    2. If you were going to pick one to be your primary string type til the end of time, which would you pick?

    Thanks
    Never take something with you for ever. New things often appear and you should always use what is the best. There are pro and cons for the string but just do a research on the forum. As for myself, when I am doing a MFC project a use CString.
    Marius Bancila
    Home Page
    My CodeGuru articles

    I do not offer technical support via PM or e-mail. Please use vbBulletin codes.

  5. #5
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968

    Re: CString -vs- std:string ?

    If you're using MFC, CString is a far better choice over std::string.
    IMHO, CString is the only MFC class that is better then the STL version.

    The std::string that comes with VC++ 6.0/7.x is very inefficient compare to CString.

    std::string peforms very badly compare to CString.

    Also IMHO, CString has a better string interface then std::string does.

    CString is also easier to code when you want to be able to compile a project to either UNICODE or ANSI.

    CString has an operator LPCTSTR(), so you don't have to explicitly cast.
    With std::string, you have to use the c_str() member function to pass the pointer.
    This point can also be consider a CON, but IMHO, the benifit far aways the down side.

    CString has a GetBuffer() function which allows you to modify the buffer directly.
    According to the C++ standard there's no portable way to modify the std::string buffer directly.

    CString has a CompareNoCase function so you can make case insensitive comparisons.

    CString works easier with many MFC and Windows API functions.

    The major CON with CString is that is not portable. However, there are some CString versions on the net that are portable.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  6. #6
    Join Date
    May 2000
    Location
    KY, USA
    Posts
    18,652

    Re: CString -vs- std:string ?

    Quote Originally Posted by Axter
    CString has a GetBuffer() function which allows you to modify the buffer directly. According to the C++ standard there's no portable way to modify the std::string buffer directly.
    Well...I do not want to get into all of the above since our view is very different from each other in this case, however....the above is not really true...there is of course a portable way...using a 'vector' as a temporary buffer...

  7. #7
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968

    Re: CString -vs- std:string ?

    Quote Originally Posted by Andreas Masur
    Well...I do not want to get into all of the above since our view is very different from each other in this case, however....the above is not really true...there is of course a portable way...using a 'vector' as a temporary buffer...
    My comment is true.
    Even if you use vector as a temporary buffer, you're still not modifying the buffer directly.
    There are many ways to modify the std::string buffer indirectly. But my comment reffers to direct modification.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  8. #8
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString -vs- std:string ?

    Quote Originally Posted by Axter
    The std::string that comes with VC++ 6.0/7.x is very inefficient compare to CString.

    std::string peforms very badly compare to CString.
    You have to show this to us in terms of real code. Badly doing what operations?
    CString works easier with many MFC and Windows API functions.
    Maybe MFC functions that require a CString, but I don't see how a Windows API function would be easier with CString as opposed to std::string.
    The major CON with CString is that is not portable. However, there are some CString versions on the net that are portable.
    And many of those versions actually wrap std::string with calls that mimic CString.
    Also IMHO, CString has a better string interface then std::string does
    The one disadvantage to CString that has not been pointed out is that std::string handles binary data easily with no tricks. I don't know if CString can handle binary data (for example, appending binary data on a CString that may contain embedded NULLs). In that respect, std::string has the functions to handle binary data (i.e, append(), data(), assign(), etc.), that AFAIK do not exist in CString.

    Regards,

    Paul McKenzie

  9. #9
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968

    Re: CString -vs- std:string ?

    Quote Originally Posted by Paul McKenzie
    You have to show this to us in terms of real code. Badly doing what operations?
    If you run the code below, you'll see the peformance difference between CString and std::string.
    Run the test in release mode (not debug).
    The code below will show that CString out peformance std::string by a factor of MORE then 10 to 1.
    Compile in VC++ 6.0 using std::string that comes with VC++.


    Code:
    int dummy_var = 0;
    
    void function1(const char*Data)
    {
         CString strData = Data;
         dummy_var += strData[99];
    }
    
    void function2(const char*Data)
    {
         std::string strData = Data;
         dummy_var += strData[99];
    }
    
    void function3(const char*Data)
    {
         CString strData;
         strData = Data;
         dummy_var += strData[99];
    }
    
    void function4(const char*Data)
    {
         std::string strData(513, 0);
         strData = Data;
         dummy_var += strData[99];
    }
    
    void function5(const char*Data)
    {
         std::string strData(999, 0);
         strData = Data;
         dummy_var += strData[99];
    }
    
    int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
    {
         const QtyTimesTest = 99999;
         DWORD StartTime, LenTime1=0, LenTime2=0, LenTime3=0, LenTime4=0, LenTime5=0;
         const int SizeData = 512;
         char DummyData[SizeData+1];
         memset(DummyData, 'x', SizeData);
         DummyData[SizeData] = 0;
         
         {
              StartTime = GetTickCount();
              for (int i = 0;i < QtyTimesTest;++i)
              {
                   function1(DummyData);
              }
              LenTime1 += (GetTickCount() - StartTime);
         }
         
         {
              StartTime = GetTickCount();
              for (int i = 0;i < QtyTimesTest;++i)
              {
                   function2(DummyData);
              }
              LenTime2 += (GetTickCount() - StartTime);
         }
         
         {
              StartTime = GetTickCount();
              for (int i = 0;i < QtyTimesTest;++i)
              {
                   function3(DummyData);
              }
              LenTime3 += (GetTickCount() - StartTime);
         }
         
         {
              StartTime = GetTickCount();
              for (int i = 0;i < QtyTimesTest;++i)
              {
                   function4(DummyData);
              }
              LenTime4 += (GetTickCount() - StartTime);
         }
         
         {
              StartTime = GetTickCount();
              for (int i = 0;i < QtyTimesTest;++i)
              {
                   function5(DummyData);
              }
              LenTime5 += (GetTickCount() - StartTime);
         }
         
         printf("Time duration is as follow:\n\
              LenTime1 = %li\n\
              LenTime2 = %li\n\
              LenTime3 = %li\n\
              LenTime4 = %li\n\
              LenTime5 = %li\n",
             LenTime1, LenTime2, LenTime3, LenTime4, LenTime5);
         if (!dummy_var) printf("dummy %i", dummy_var);
         system("pause");

    Quote Originally Posted by Paul McKenzie
    Maybe MFC functions that require a CString, but I don't see how a Windows API function would be easier with CString as opposed to std::string.
    Example:
    int MessageBox(
    HWND hWnd, // handle to owner window
    LPCTSTR lpText, // text in message box
    LPCTSTR lpCaption, // message box title
    UINT uType // message box style
    );
    Code:
    CString CstrData = _T("Hello");
    std::string stdStrData = "Hello";
    
    MessageBox(NULL, CstrData, NULL, 0); //Compiles on UNICODE and ANSI
    MessageBox(NULL, stdStrData.c_str(), NULL, 0); //Only compiles on ANSI (need wstring for UNICODE)
    The CString variable is handed over to the API function directly, without having to call a member function. Moreover, it compiles on UNICODE and ANSI projects without having to modify the code, or create another compiler directive.

    Quote Originally Posted by Paul McKenzie
    And many of those versions actually wrap std::string with calls that mimic CString.
    I agree.

    Quote Originally Posted by Paul McKenzie
    The one disadvantage to CString that has not been pointed out is that std::string handles binary data easily with no tricks. I don't know if CString can handle binary data (for example, appending binary data on a CString that may contain embedded NULLs). In that respect, std::string has the functions to handle binary data (i.e, append(), data(), assign(), etc.), that AFAIK do not exist in CString.
    CString can also handle binary data.
    Example code:
    Code:
    	char data1[] = "\0\1\2\3\4\5\6\7 Hello World";
    	char data2[] = "\0\7\6\5\4\3\2\1";
    	CString binData(data1, sizeof(data1)-1);
    	binData += CString(data2, sizeof(data2)-1);
    	for (int i = 0;i < binData.GetLength();++i)
    	{
    		cout << (int)binData[i] << endl;
    	}
    	system("pause");
    More over, the GetBuffer() function can be used similar to the data() function of std::string.
    I agree that not having an assign() nor an append() function is a limitation on the CString class. And I'm surprise MS didn't include these functions.
    However, you can do an append by using the += operator as in my above example. And an assign can be done by either iterating through each position via SetAt, or modifying the buffer directly via GetBuffer() function.

    A lot of critics of CString, don't fully understand the class, and don't realize the average peformance value.
    Last edited by Axter; November 30th, 2004 at 05:24 PM.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  10. #10
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString -vs- std:string ?

    f you run the code below, you'll see the peformance difference between CString and std::string.
    Run the test in release mode (not debug).
    The code below will show that CString out peformance std::string by a factor of MORE then 10 to 1.
    Compile in VC++ 6.0 using std::string that comes with VC++.
    Do a reserve() on the string before using it. Then you should see hardly any difference.

    Almost all of the standard container classes, including std::string, has a reserve() method that addresses the issue that you demonstrated in your code. The ones that don't are the associative types (maps).

    In general, what usually ends up in real code is a series of many concatenations on one string. Why not run a benchmark on that, since that is what is more likely to be done in a real application.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; November 30th, 2004 at 06:34 PM.

  11. #11
    Join Date
    Apr 1999
    Location
    Altrincham, England
    Posts
    4,470

    Re: CString -vs- std:string ?

    You're not being fair to std::string with your ANSI vs UNICODE example. Add this to your project:
    Code:
    #ifdef _UNICODE
    typedef tstring std::wstring;
    #else
    typedef tstring std::string;
    #endif
    and we're on a more equal footing, since that's what happens with CString, anyway. Then the only difference is between the two is that you have to call the c_str() function on the tstring. To my mind that is a distinct advantage that string has over CString. Take the implicit conversion out of CString and it will be a much better class. I also don't like the GetBuffer() function of CString - it opens it up to all sorts of potential problems.
    Correct is better than fast. Simple is better than complex. Clear is better than cute. Safe is better than insecure.
    --
    Sutter and Alexandrescu, C++ Coding Standards

    Programs must be written for people to read, and only incidentally for machines to execute.

    --
    Harold Abelson and Gerald Jay Sussman

    The cheapest, fastest and most reliable components of a computer system are those that aren't there.
    -- Gordon Bell


  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString -vs- std:string ?

    Also, I ran your code. There is hardly any difference in the times, even without reserve():
    Time duration is as follow:
    LenTime1 = 109
    LenTime2 = 141
    LenTime3 = 93
    LenTime4 = 188
    LenTime5 = 203
    Running VC 6.0, Pentium 4, 3.00 GHZ

    Regards,

    Paul McKenzie

  13. #13
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968

    Re: CString -vs- std:string ?

    Quote Originally Posted by Graham
    You're not being fair to std::string with your ANSI vs UNICODE example. Add this to your project:
    Code:
    #ifdef _UNICODE
    typedef tstring std::wstring;
    #else
    typedef tstring std::string;
    #endif
    and we're on a more equal footing, since that's what happens with CString, anyway. Then the only difference is between the two is that you have to call the c_str() function on the tstring. To my mind that is a distinct advantage that string has over CString. Take the implicit conversion out of CString and it will be a much better class. I also don't like the GetBuffer() function of CString - it opens it up to all sorts of potential problems.
    That is not exactly what happens with CString. The CString type char itself is change instead of the entire object.

    IMHO, the advantages of implicit conversion out ways the disadvantages.
    I guess we'll have to agree to disagree.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  14. #14
    Join Date
    Aug 2000
    Location
    New Jersey
    Posts
    968

    Re: CString -vs- std:string ?

    Quote Originally Posted by Paul McKenzie
    Also, I ran your code. There is hardly any difference in the times, even without reserve():

    Running VC 6.0, Pentium 4, 3.00 GHZ

    Regards,

    Paul McKenzie
    Did you run it in release or debug mode?
    Those results look like debug results, and not release.

    FYI:
    Even in your results, the std::string is about 40% slower the CString.
    That's a big difference to me.

    And using reserve is not a valid argument for this test. You don't always know the size that you're going to need for your buffer in advance.
    Last edited by Axter; November 30th, 2004 at 06:36 PM.
    David Maisonave
    Author of Policy Based Synchronized Smart Pointer
    http://axter.com/smartptr


    Top ten member of C++ Expert Exchange.
    C++ Topic Area

  15. #15
    Join Date
    Apr 1999
    Posts
    27,449

    Re: CString -vs- std:string ?

    Release mode (maximize speed).

    For debug, I get these numbers:
    Time duration is as follow:
    LenTime1 = 234
    LenTime2 = 203
    LenTime3 = 344
    LenTime4 = 422
    LenTime5 = 437
    Regards,

    Paul McKenzie

Page 1 of 4 1234 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured