|
This is great class. In function StdCodeCvt another neat way to covert from to wide characters is:
To char:
std::string dst;<br />
std::wstring src = L"Convert me";<br />
<br />
dst.assign(src.begin(), src.end());
And to wchar_t:
std::wstring dst;<br />
std::string src = "Convert me";<br />
<br />
dst.assign(src.begin(), src.end());
Thank you for the great class
|
|
|
|
|
take care locale
Hardware-OS-Software
===== Bridge =======
|
|
|
|
|
Hi Joe,
I have ported the library onto MAC and using it to build extensions for firefox. I created two toolbars for firefox and both the toolbar has the stdstring.h libary used in it. When I load firefox with both the toolbars, the browser crashes and stack trace shows inside stdstring.h. When I load firefox with any one, then I see no crashes at all.
Pls. let me know if you have got any version of this library for MAC OS X 10.5.
Thanks,
krissam
|
|
|
|
|
Hi,
I really only have one version of the file. I use compiler directives to make it build on various plaforms. Unfortunately the version on CodeProject is a bit out of date and I have not updated it because I don't like the fact that they want me to apply some sort of license to it.
I am on vacation right now but will be happy to help you get this working when I get back on Monday, Oct 26. In the meantime, if you could email me (my address is right in the header file and is still valid ) and include the version of the file you are using and some indication of the code that's causing the problem as well as the error itself, I should be able to see what is up.
Actually the problem might just be that you have an out of date version of the file (again, due to my reluctance to update the version hosted here). So email me directly and I'll send you the latest version. It might help
-Joe
-Joe
|
|
|
|
|
Hi Krissam,
I am so sorry I never finished helping you with this. At first I thought I never responded at all (my reply was on the second page) but now I see that I did yet I never followed up.
I hope you were able to resolve the problem. If, by chance, you are still using the code there IS a new version here for download
-Joe
|
|
|
|
|
I've just attempted to compile this file in VS2010 Beta 2, but unfortunately it won't compile.
Other than a bunch of deprecation warning messages, the compiler gets stuck here:
inline CArchive& AFXAPI operator<<(CArchive& ar, const CStdStringA& strA)
{
CString strTemp = strA;
return ar << strTemp;
} ... error C2440: 'initializing' : cannot convert from 'const CStdStringA' to 'ATL::CStringT<basetype,stringtraits>'
Since the ClassWizard is back in VS2010, I am at last considering to move up from VC6, so any help would be very much apreciated in order to get this class up to date.
Thank you.
|
|
|
|
|
Hi,
Looks like you have an old copy of the code. I really need to update the one on CodeProject. The one I have locally is up-to-date. If you email me at jmoleary@earthlink.net I can send it to you.
If you don't feel like emailing me, the simplest solution is to delete all of the operator<< functions that include CArchive. They're all right there in a block of text so it's pretty quick to do. Unless you are using CArchive to serialize CStdString objects (something that few people are doing, I imagine) you will never need them.
OR... if you want to keep them and still don't want to email me, you can change that line to use a constructor instead of assignment. Make it look like this
CString strTemp(strA)
That was fix I applied way back when-Joe
|
|
|
|
|
Thanks a lot for this good class.
And:
1. How about hosting this code on codeplex, gcode or sf?
2. It could be better if it had UTF8 related conversion methods.
Regards,
modified on Thursday, January 21, 2010 3:51 AM
|
|
|
|
|
Joe you have outdone yourself here. This is the ultimate cstring
|
|
|
|
|
Thanks,
I've been updating the thing on and off for about 13 years now!
Be sure to check the link inside the header to make sure you have the very latest version. I haven't updated the CodeProject one for a while now. Keep meaning to get around to it.
-Joe
|
|
|
|
|
#define CStdString CStringEx
CStringEx GetLogHeader(BOOL bLocalTime = TRUE)
{
SYSTEMTIME st;
bLocalTime ? GetLocalTime(&st) : GetSystemTime(&st);
DWORD dwPID = GetCurrentProcessId();
DWORD dwTID = GetCurrentThreadId();
CStringEx strPID = _T("Unknown");
CStringEx strTID = _T("Unknown");
CStringEx strLogHeader;
strLogHeader.Format(_T("[%02d:%02d:%02d(%03d)][0x%04X:%s][0x%04X:%s]"),
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, dwPID, strPID.c_str(), dwTID, strTID.c_str());
return strLogHeader;
}
void WriteLogDebug(TCHAR *ch, ...)
{
TCHAR buf[1024];
va_list arg_list;
va_start( arg_list, ch );
_vstprintf_s( buf, _countof(buf), ch, arg_list );
va_end( arg_list );
OutputDebugString(buf);
FILE *file = NULL;
errno_t err = _tfopen_s(&file, g_szLogFile, _T("a+"));
if (!err)
{
_ftprintf_s(file, _T("%s%s"), GetLogHeader().c_str(), buf);
fclose(file);
}
}
The above code works works fine except that it does not print Hangul(Korean) characters correctly. It prints them in question(0x3F marks (?????) only. The source code was built in UNICODE mode. Try the following call.
WriteLogDebug(_T("한글을 씁시다\n"));
I tried to figure out/fix this issue for so long, but failed.
Can someone help?
HR
|
|
|
|
|
I see you posted this in June. Sorry I did not notice it until now. It is probably far too late to help you but I will post this anyway.
The problem is likely one of locale. You need to set the locale to the global one
The way to set the global locale is as follows:
std::locale loc2 ("korean");<br />
std::locale::global(loc2);
You could do this once at the start of your program.
-Joe
|
|
|
|
|
|
The following code works wrong.
SYSTEMTIME st;<br />
GetLocalTime(&st);<br />
DWORD dwPID = GetCurrentProcessId();<br />
DWORD dwTID = GetCurrentThreadId();<br />
CStdString strPID = _T("UN");<br />
CStdString strTID = _T("UN");<br />
<br />
CStdString str;<br />
str.Format(_T("[%02d:%02d:%02d(%03d)][0x%04X:%s][0x%04X:%s]"),<br />
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, dwPID, strPID, dwTID, strTID);<br />
CStdString str2;<br />
str2.Format(_T("[%02d:%02d:%02d(%03d)][0x%04X:%s][0x%04X:%s]"),<br />
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds, dwPID, strPID.c_str(), dwTID, strTID.c_str());<br />
FILE *file = NULL;<br />
errno_t err = _tfopen_s(&file, g_szLogFile, _T("w"));<br />
if (!err)<br />
{<br />
TCHAR buf[1024]; <br />
_ftprintf_s(file, _T("%s%s"), str, buf);<br />
_ftprintf_s(file, _T("%s%s"), str.c_str(), buf);<br />
_ftprintf_s(file, _T("%s%s"), str2, buf);<br />
_ftprintf_s(file, _T("%s%s"), str2.c_str(), buf);<br />
fclose(file);<br />
}<br />
This is run using VC2005/WinXP SP3.
Please check if fixable.
HR
|
|
|
|
|
The problem is exactly what you identified in the title of your post. You are using a CStdString object as a POD type when it is not one.
Whenever you pass a CStdString as one of the "variadic" parameters to a function like fprintf (i.e. one of the "..." parameters), you must be sure to properly cast it to the proper POD type first. Otherwise, the compiler will simply take the first 4 bytes of the object in binary layout.
So this line is bad:
_ftprintf_s(file, _T("%s%s"), str, buf);
but this line is OK
_ftprintf_s(file, _T("%s%s"), str.c_str(), buf);
Other variations that would be OK include the following:
_ftprintf_s(file, _T("%s%s"), str.GetString(), buf);
_ftprintf_s(file, _T("%s%s"), static_cast<PCTSTR>(str), buf);
Yes, I realize that MFC's CString lets you get away without doing this, but they specifically laid out the class in binary to allow it. In short, it's a hack they put in there to protect you from yourself.
Since I derive CStdString from whatever implementation of basic_string your library provides, I have no control over the binary layout of the class.
-Joe
|
|
|
|
|
Joe,
yes, I knew the .c_str() works, but I thought removing it would be ok using the extension posted by balint256 in this thread. And so asked him if this usage was one of his points of extension.
CStdString str(_T("world!"));
_tprintf(_T("Hello %s\n"), str);
// Output is "Hello world!"
Otherwise, I don't see what is the point of the extension.
|
|
|
|
|
Sorry, I somehow missed that this was a response to his post.
I must admit I haven't looked at his scheme until now. Now that I have, I would not recommend it. He adds to the size of the class, introduces multiple inheritance and must update a pointer after every single function call, yet he fails to update that pointer in all places needed. All to avoid a simple call to c_str() in rarely called functions.
The only reason I ever created my CStdString::Format "hack" in the first place, was because it improves the safety of the class, and in no way reduces it. Unfortunately, balint's fix does not do that. I do not mean to criticize balint. He clearly wanted to help. But I cannot recommend this fix as it is incomplete and decreases the safety of the code.
Also, my fix was purely for those converting legacy code. Not for new code. If you are writing new code, do yourself a favor: Every time you call a variadic function with a CStdString arguments, call the c_str() function on the argument. It's what I do.
-Joe
modified on Tuesday, June 16, 2009 9:49 AM
|
|
|
|
|
Got it. Thanks for the clarification, otherwise, I would have to waste time to figure out why balint's extension not working.
I will go back to the original one.
BTW, I sent you an email asking for the newest source with project if possible. Did you get it?
|
|
|
|
|
Oh that was an email? I put that aside thinking, "I'll get to this later today". Then when I tried to, I kept looking for a post about it here and couldn't see it.
Will go back, find it, and send you the latest.
-Joe
|
|
|
|
|
Hi everyone.
Can't get the demo project to work
Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""class CStdStr<char> __cdecl operator+(class CStdStr<char> const &,char const *)" (??H@YA?AV?$CStdStr@D@@ABV0@PBD@Z)" in Funktion "_main". TestString.obj
Any idea?
|
|
|
|
|
Hi,
It has been ages since I updated that project file. I think I generated it with Visual Studio 6 or earlier. Unfortunately, the VS Upgrade wizard doesn't seem to properly upgrade it for me either. So I went and created a new one. You can do it yourself if you want or you can get it from me. Doing it is pretty simple. Just
1. create a new console project.
2. Add the 2 string resources that were in the old project(IDS_STRING1 and IDS_STRING2) and put whatever values in them you want.
3. Move the code from TestString.cpp in the old file to the new file. Don't forget the #include statements.
You might, however want to get the latest version of the header file. You can email me and I'll send it to you, along with the updated project file, if you prefer.
-Joe
|
|
|
|
|
Hi,
I am using CStdString in a WTL project and I had some issues because when using atltime.h I get :
>C:\Program Files\Microsoft Visual Studio 9.0\VC\ce\atlmfc\include\atltime.h(281) : error C2039: 'Preallocate' : is not a member of 'CStdStr<ct>'
This error also occurs with the WTL::CString and it seems Preallocate it's only declared in
ATL::CString version in atlsimpstr.h :
void Preallocate( _In_ int nLength )
{
PrepareWrite( nLength );
}
PXSTR PrepareWrite( _In_ int nLength )
{
CStringData* pOldData = GetData();
int nShared = 1-pOldData->nRefs;
int nTooShort = pOldData->nAllocLength-nLength;
if( (nShared|nTooShort) < 0 )
{
PrepareWrite2( nLength );
}
return( m_pszData );
}
How can we make the same things with CStdString ?
|
|
|
|
|
Hi,
Over the years, as Microsoft has updated CString, it has been difficult keeping CStdString up to date with it. Preallocate is certainly a function added in recent versions, I guess when they changed the hierarchy to have CSimpleStringT and CStringT
At first glance it looks like it just ensures the buffer is the requested size. I still have to determine the rules (i.e. should the buffer be shrunk if it is larger? Is existing data preserved? etc) but it should not be too hard to implement.
A crude implementation might be something like this
void Preallocate(int nLength)
{
if (this->GetLength() < nLength)
{
this->resize(nLength);
}
}
Note that this example assumes a string that's already longer than the requested length would not need to be truncated.
I'll have to look into this a bit closer though.
-Joe
|
|
|
|
|
Hi Vincent,
To use CStdString a ATL::CSimpleString (not WTL::CString), in your stdafx.h:
#define __ATLSIMPSTR_H__
#include <atlbase.h>
#include "StdString.h"
#define Preallocate(size) reserve(size)
namespace ATL
{
typedef ::CStdString CSimpleString;
};
#define __ATLSTR_H__
cheers,
AR
|
|
|
|
|
Hi,
Does someone know how to solve this :
CStdString strFolder;
m_treeFolder.GetItemText(hItem, strFolder);
BOOL WTL::CTreeViewCtrlT<tbase>::GetItemText(HTREEITEM,BSTR &) const' : cannot convert parameter 2 from 'CStdString' to 'BSTR &'
and GetItemText has 3 overloads :
BOOL GetItemText(HTREEITEM hItem, LPTSTR lpstrText, int nLen) const;
BOOL GetItemText(HTREEITEM hItem, BSTR& bstrText) const;
BOOL GetItemText(HTREEITEM hItem, _CSTRING_NS::CString& strText) const;
I would like to use the third one with CString reference, is it possible to
make CStdString compatible with CString& ? Even simpler I would like to write :
CString strFullPath;
CStdString& str = strFullPath;
|
|
|
|
|