|
I am trying to compile this on FreeBSD 4.7 with GCC 2.95.4 and with STLport 4.5.3 and I get these errors.
StdString.h:442: `mbstate_t' was not declared in this scope
StdString.h:442: template argument 3 is invalid
StdString.h:442: confused by earlier errors, bailing out
*** Error code 1
Thanks
|
|
|
|
|
Hi,
Two things. First of all, you need G++ 3.x. 2.xxx always gives people problems. I know some people managed to make 2.95xxx work with some hacks, but take my word for it -- get 3.x. They improved the Standard Library implementation.
Second make sure you have the very latest version which you can always get here:
Latest version
-Joe
|
|
|
|
|
Thank you for the quick respons. I have now installed GCC31 and now when I compile with g++31 it gives me this error.
******************************************************
StdString.h: In function `wchar_t* StdCodeCvt(wchar_t*, const char*, int, const
std::locale&)':
StdString.h:678: warning: aggregate has a partly bracketed initializer
StdString.h: In function `char* StdCodeCvt(char*, const wchar_t*, int, const
std::locale&)':
StdString.h:701: warning: aggregate has a partly bracketed initializer
StdString.h: In function `int ssvsprintf(wchar_t*, unsigned int, const
wchar_t*, char*)':
StdString.h:1342: `vswprintf' undeclared (first use this function)
StdString.h:1342: (Each undeclared identifier is reported only once for each
function it appears in.)
In file included from x10cgi.cpp:7:
StdString.h:3729:31: warning: no newline at end of file
x10cgi.cpp: At global scope:
x10cgi.cpp:10: warning: ISO C++ forbids declaration of `main' with no type
x10cgi.cpp: In function `int main(int, char**)':
x10cgi.cpp:17: warning: passing `double' for argument passing 2 of `size_t
fread(void*, unsigned int, unsigned int, FILE*)'
x10cgi.cpp:17: warning: argument to `unsigned int' from `double'
x10cgi.cpp:12: warning: unused variable `int i'
*** Error code 1
********************************************************
Thanks
Joe Doran
|
|
|
|
|
hi,
First, Thanks for the great class.
I'm not an expert C++ programmer, so maybe I'm doing something wrong.
I get access violation when i use CStdString in CMapStringToOb
typedef CTypedPtrMap<cmapstringtoob,cstdstring,clane*> CMapStringToCLane;
CMapStringToCLane gmapLaneIDToCLane;
POSITION pos = gmapLaneIDToCLane.GetStartPosition();
while (pos != NULL)
{
CStdString str;
CLane* pLane;
gmapLaneIDToCLane.GetNextAssoc(pos, str, (CLane*&)pLane);
}
thanks,
vish
Passing through planet earth Glad you are too
|
|
|
|
|
Hi Vish. I have a few questions/comments. I hope that you find at least one or two of these helpful or at least enough to put you on the right track. If not, please respond back and I will try to help. Also, if you respond again, please let me know what version of MFC and MsDev you are using.
1. If you are using CTypedPtrMap, that means you are using MFC. That means you have CString. Why use my class (a CString clone) if you already have CString in the first place? Don't get me wrong, I like my class just fine, but you don't need it.
2. You are using CTypedPtrMap incorrectly. It is a template. Where are the template arguments? You must supply template arguments to it. You have not done this. For example (it's been a long time since I used it but I seem to recall it is something like this):
typedef CTypedPTrMap <CMapStringToPtr, CString, CLane > CMapStringToCLane
3. According to the MSDN documentation, the first template argument to CTypedPtrMap must be one of the following:
-CMapPtrToPtr
-CMapPtrToWord
-CMapWordToPtr
-CMapStringToPtr
If you are using strings as keys, that means CMapStringToPtr. However that class requires a real CString, not CStdString. I'm not sure that CStdString can really subsititute in there. It might work as a CString but the compiler won't treat it as exactly the same type.
4. If you are going to use collections, I strongly recommend you forget about MFC collection classes like CTypedPtrMap and instead use the Standard C++ Library collections like std::map, std::list, etc. They are much more portable and much easier to use, once you get the hang of them.
5. By the way, even if you were using CTypedPtrMap, there should be no need for you to explicitly cast 'pLane" to a 'CLane*&'. It already IS one. You should be able to write the line like this:
gmapLaneIDToCLane.GetNextAssoc(pos, str, pLane);
But of course, there are other problems (like the template argument thing I already mentioned) that you need to address before worrying about this one
Hope some of this is helpful
-Joe
|
|
|
|
|
thank you sir for the prompt reply.
I'M in a learning phase
i didn't know about map,list in STL.
maybe that is the way i should take.
maybe i need to get some good STL books.
I'm useing VC++6.0
STL Dinkumware
thank you.
vish
passing through planet earth glad you are too
|
|
|
|
|
|
The StdString::Format method, compiled using SS_ANSI, allocates a buffer of 1024 bytes and then calls the 'vsprintf' function.
vsprintf accepts the buffer but makes no attempt to check whether it's large enough to hold the values of the passed arguments (the buffer size isn't part of its signature). If the total space of the substituted values is greater than 1024 we get a memory overwrite.
|
|
|
|
|
This is because vsprintf cannot take a buffer larger than 1024. At least not on my platform. The formatted message either fits in there or it does not. Short of parsing the string character by character (and format specifier by format specifier) to determine the length dynamically allocate buffers, etc.
-Joe
|
|
|
|
|
Thanks for the reply.
I'm playing with a vsnprintf function that does take the buffer length and returns either the number of characters witten, -1 or the required length.
If this works then the code in (my copy of) FormatV will look very similar whether it's SS_ANSI or not, i.e. using a dynamic local buffer in a loop for the call to ssvsprintf (which will return whatever vsnprintf returns) and then calling assign at the end.
Not sure whether vsnprintf is ISO/ANSI standard or whether it has a max buffer length, the man page doesn't list any restrictions. We'll see.
Rod
|
|
|
|
|
Hi Rod,
I definitely looked at vsnprintf when I was writing the ANSI version of Format() long ago. Unfortunately, the only docs I had to go on were MSDN and they listed vsnprintf as a non-standard function. That is why I ended up using vsprintf.
In fact, even with functions that are supposed to be standard I had all kinds of problems. If you look closely at all that code around vswprintf, you'll see the hoops I had to go through to make it build on all platforms. In short, it seems half the platforms out there do not conform to the standard even in the signature of the function!
If you get it to work with vsnprintf, great, I suppose I could change my lowest-common-denominator approach to allow people to at least TRY that function. It's just that I've always understood it could not be relied upon to be there.
(another function like this is the alloca() function. You'll see me using it all the time with Win32 because I know it's there. Actually it's on many other platforms too but, since it's not standard, I cannot rely upon it being there.
-Joe
|
|
|
|
|
I just noticed this when trying to trim a string that has extended ASCII characters. CStdString is using isspace to see if a character is a space or not before trimming it. Problem is, if you pass a character in that has a value < 0, it will wind up causing an ASSERT. This seems to be a problem with Visual .NET's isspace function... it tries to cast it to unsigned and see if it is less than 256, but it seems to be failing miserably.
Has anyone else seen this besides me? Is there any way to get around this? I could, in theory, hack up CStdString and add a quickie function to take care of this (e.g., adding "myisspace" that will return false if the character's ASCII value is less than 0).
But I want to make sure I'm not doing something wrong or missing something obvious. Thanks.
"When a man sits with a pretty girl for an hour, it seems like a minute. But let him sit on a hot stove for a minute and it's longer than any hour. That's relativity." - Albert Einstein
|
|
|
|
|
Sorry to have taken so long to respond to this. I've been very lax in checking this board lately and I don't know what's happening to the auto-notify emails.
Does this still happen with the very latest version of CStdString? If so, please let me know.
As far as the isspace function goes, I am torn between using good old "C" style isspace/iswspace and using std::isspace. I don't know if std::isspace will solve your problems but you might as well give it a try. The current version uses it.
My only reluctance to use it comes from a Dinkumware but that affects COM DLLs which use this function. I describe it in the header. But I am no longer using the "workaround" for that bug because the latest version of Dinkumware's library does not appear to have it.
|
|
|
|
|
FILE *fp;
fp = fopen("c:\\temp.txt", "w" );
CStdString str;
str = "Something here!!";
fprintf(fp, "%s\n", str ); // bug here
|
|
|
|
|
CStdString str;
str = "Something here!!";
fprintf(fp, "%s\n", str.GetBuffer(str.GetLength()) ); // OK here
str.ReleaseBuffer();
|
|
|
|
|
This is not a bug. You just need to be sure to call c_str() on the CStdString object whenever you supply it as one of the "..." arguments in a variadic function like fprintf, sprintf, CStdString::Format, etc.
It's true that MFCs CString allows you to get away with just this:
fprintf(fp, "%s\n", str);
But that is a hack and is not something you should rely upon. Even Microsoft recommends you cast CString when supplying it as one of the "..." arguments in a function like fprintf:
fprintf(fp, "%s\n", (const char*)str);
...or you could do this:
fprintf(fp, "%s\n", static_cast<const char*>(str));.
.and with CStdString, you can do this as well.
fprintf(fp, "%s\n", str.c_str());
All three examples above have the exact same effect -- turning the CStdString object into a const char*. A const char* is what fprintf needs to supply to the %s, not a CStdString.
Whatever you do, don't call GetBuffer(). That's for getting NON-const access to the string buffer. You don't need a writeable buffer string buffer. You need a read-only one, a const char*
If you read the other feedback to the CStdString article you'll see this question asked many times. You might need to adjust the date filter to see all the feedback. But once again, this is not a bug. It is an annoyance caused by variadic functions (i.e. functions that take a variable number of arguments) and it is something I cannot possibly design around. Read the other feedback for a more thorough explanation.
|
|
|
|
|
Thanks!
|
|
|
|
|
|
First off, thank you for this class. It's been extremely helpful. I'm compiling for the first time on UNIX (SunOS 5.8) and getting several errors (e.g., DWORD not defined) all within the "ssfmtmsg" function below. Based on the header comment, I'm guessing the #else may be out of place, but then I'd be surprised it wasn't caught sooner. Please let me know if I'm doing something wrong. Thanks for your help.
// -----------------------------------------------------------------------------
// ssfmtmsg: FormatMessage equivalents. Needed because I added a CString facade
// Again -- no equivalent of these on non-Win32 builds but their might one day
// be one if the message facet gets implemented
// -----------------------------------------------------------------------------
#if defined (SS_WIN32) && !defined(SS_ANSI)
#else
inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId,
DWORD dwLangId, PSTR pBuf, DWORD nSize,
va_list* vlArgs)
{
return FormatMessageA(dwFlags, pSrc, dwMsgId, dwLangId,
pBuf, nSize,vlArgs);
}
inline DWORD ssfmtmsg(DWORD dwFlags, LPCVOID pSrc, DWORD dwMsgId,
DWORD dwLangId, PWSTR pBuf, DWORD nSize,
va_list* vlArgs)
{
return FormatMessageW(dwFlags, pSrc, dwMsgId, dwLangId,
pBuf, nSize,vlArgs);
}
#endif
Bill
|
|
|
|
|
Well a DWORD is an unsigned long, but I think that's not the problem here. The problem is that I appear to have misplaced my preprocessor macros. I put the
#else
line in the wrong place. It should be BELOW those ssfmtmsg functions, not above them. If you move it downward to the correct spot, you should be OK.
FormatMessageA and FormatMessageA only exist on Win32 platforms.
I will correct the online version tonight. Sorry about that.
-Joe
|
|
|
|
|
we develop windows program with vc(but not use MFC).
Our program complied ,and display follow warning:
/***************************************************/
warning C4786: 'std::_Tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<std::basic_string<char,std::char_traits<char>,std::allocator<c
har> > const ,CMarkupSTL::SavedPos>,std::map<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,CMarkupSTL::SavedPos,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<cmarkupstl::savedp
os> >::_Kfn,std::less<std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::allocator<cmarkupstl::savedpos> >' : identifier was truncated to '255' characters in the debug information
/***************************************************/
CMarkupSTL is the class that encapsulates the dom object.
As using the template, the symbol lenght may be less than 255.
Display the warning,why?
|
|
|
|
|
It is a warning very common with Visual C++ and the Standard C++ Library. What it is telling you is that the fully decorated C++ name of a class (instantiated from a template) was longer than 255 characters. That's a problem with templates and VC.
It is harmless but annoying.
If you wish to suppress this warning, you may use a #pragma as follows:
#pragma warning (disable:4786)
Place this pragma as early in the header as you can. I put all such #pragmas in my stdafx.h
Please note however that some VC headers actually turn ON warnings you might have disabled with this statement. In particular the header <yvals.h> does this. Therefore you might need to do something like this
#pragma warning (disable:4786) // disable it
#include <yvals.h> // this will re-enable it
#pragma warning (disable:4786) // disable it AGAIN
Bizarre but it works.
Again, don't worry about the warning. It is completely harmless.
-Joe
|
|
|
|
|
I'm pleasantly suprised that you reply soon.
I'm worring about the worning.
Thank you very much!
|
|
|
|
|
I'm pleasantly suprised that you reply soon.
I'm worring about the worning.
Thank you very much!
|
|
|
|
|
I'm working on a large (personal) project comprising of several DLLs and EXEs. I want to use this string class as a common string type for all projects so i can pass this to the DLLs exported functions. I understand if i use this string header in each separate project it might cause problems because it uses the stl and what if one of the DLLs uses a different stl library to the lib file? what will happen then?
So i wanted to put the implementation of this string class inside a lib file, so the stl implementation is common (at least in the lib) and then i can just include the header (which is not the class definition only) in the projects and also link to the lib file. Is this possible?
Thank you!
|
|
|
|
|