|
Thanks!
I got the solution
It is just to change the SetFormat() finction and not to pass tt t options in string
|
|
|
|
|
Hello,
porting my sipmle (hope, C++ standard conforming) console programs from VC++ 2003 to VC++2005 I found out that I can't read unsigned int from the stream if there is a comma after it.
...main...{
unsigned int ui=2345;
cin >> ui;
cout << ui; // still will show 2345 on input "1,1"
}
Input "1,1" prevents reading 1 to ui. The reason is that deep inside the num_get class of the VC2005 iostream library thinks that in the current locale comma is thousand separator. But there is no reason for it. (I don't even mention locales in my program, so it should be standard "C" locale.)
Any sensible suggestions? I want (and could before) reading
// This also affects boost::uBLAS library at matrix input.
Regards,
Alex
|
|
|
|
|
wrote: (I don't even mention locales in my program, so it should be standard "C" locale.)
That's a bold (and invalid) assumption. The locale is set by the OS. It's up to the programmer
to ensure that locale-specific functions are behaving as expected.
|
|
|
|
|
Well, thanks for your answer anyway.
In fact, it was a sort of VC2005 bug. Service Pack helped me.
As far as I know, the C++ program should start with standard "C" locale no matter the OS reports.
Best regards,
Alex
|
|
|
|
|
|
Thank you very much for the info!
As I mentioned in prev message, SP1 fixes the bug.
Regards,
Alex
|
|
|
|
|
Could any1 plz tell me how can i get current time in milliseconds.
thanks.
|
|
|
|
|
ikbahrian wrote: get current time in milliseconds.
SYSTEMTIME st;
GetSystemTime(&st);
I hope this helps.
Somethings seem HARD to do, until we know how to do them.
_AnShUmAn_
|
|
|
|
|
|
Hi. Im using VC6 and trying to swap byte as the file is little endian.
<br />
while (j < 20)<br />
{ <br />
array[j] = file.get();<br />
j++;<br />
}<br />
<br />
j = 0;<br />
<br />
for (i=0; i<10; i++)<br />
{<br />
swap[i] = ((int)array[j+1] << 8) + array[j];
j = j + 2;<br />
}<br />
Is the swapping method correct? Coz I cant seem to get the correct ans.
|
|
|
|
|
array is a char array ? and swap is an int array ? int is four bytes, not two. Try a short array, or just swap in place
for (i=0; i<10; i+=2)<br />
{<br />
byte temp = array[i];<br />
array[i] = array[i+1];<br />
array[i+1] = temp;<br />
}<br />
<br />
That's more efficient than doing shifts as well, I would presume.<br />
Christian Graus - C++ MVP
'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert
|
|
|
|
|
yeah. array is a char array and swap is an int array.
Im opening a file stream to read in some bytes like: 2E FA CC F6 9F FC and store it in array. So since its little endian, I want to swap the position of the first element of array with the position of the second element of array. And then store both array[0] and array[1] into int swap[0] to do some calculation.
That can be done right? since int is 4 bytes which is equalvalent to 2 char.
What is the best way to do that?
|
|
|
|
|
ReturnRain wrote: since int is 4 bytes which is equalvalent to 2 char.
No, a char is always one byte.
|
|
|
|
|
ReturnRain wrote: What is the best way to do that?
As Mike said ( and I said before him ) a byte is a char. They are the same thing. Do what I suggested in the first place.
Christian Graus - C++ MVP
'Why don't we jump on a fad that hasn't already been widely discredited ?' - Dilbert
|
|
|
|
|
Say I have a string key from an INI file. What is the best way to instantiate an object depending on this key? Something like:
if (strKey == "cat") m_pPet = new CCat();
else if (strKey == "dog") m_pPet = new CDog();
else if (strKey == "monkey") m_pPet = new CMonkey();
...
When the list of classes getting longer and longer, the above way is too tedious and hard to maintain. I thought about runtime information but don't know how to tackle this problem with that.
__________________________
S.C.
|
|
|
|
|
There is no problem with your method of creating instances.
If I were to tackle the same problem, I would first convert the strkey into a DWORD value, then use a switch statement rather than comparing the string each time. Also, I would convert the strKey to lower-case before doing any comparison.
|
|
|
|
|
S.C.Wong wrote: When the list of classes getting longer and longer, the above way is too tedious and hard to maintain.
How so? Each additional animal requires 1-2 lines of code.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
S.C.Wong wrote: Something like:
if (strKey == "cat") m_pPet = new CCat();
else if (strKey == "dog") m_pPet = new CDog();
else if (strKey == "monkey") m_pPet = new CMonkey();
...
Personally, I would put this into a PetFactory -Class, which has a static method
Pet* CreatePet( const std::string& PetType);
With basically your logic inside.
Your call would look like this:
PetFactory factory;
m_pPet = factory.CreatePet( "cat");
Maybe the Petfactory would be a singelton or a member.
This way, You may later change the way the connection string<->pet-derived class is done. Maybe you want it configurable by a file?
Simply give the file to the PetFactory , change the PetFactory internals to build a map string<->c'tor and youre done.
"We trained hard, but it seemed that every time we were beginning to form up into teams we would be reorganised. I was to learn later in life that we tend to meet any new situation by reorganising: and a wonderful method it can be for creating the illusion of progress, while producing confusion, inefficiency and demoralisation."
-- Caius Petronius, Roman Consul, 66 A.D.m_PetFactory
|
|
|
|
|
You can use a factory pattern to that: create a factory class which is a singleton (if you don't know what the singleton design pattern is, I suggest you make a search on the web, you'll get better explanations that I can give you ).
This class provide a function that is able to create a class depending of a certain key (in your case, its name). Of courses, all classes must inherits from a common base class (animal in your case).
The factory in fact consist simply of a map in which each entry link a key (animal name) to a function pointer which can create a specific instance of your class (e.g. a dog).
So, the create function simply looks up in the map for the specific creation function, calls it and returns the newly created object.
Next, this factory needs to expose a way to add new entries in your map. This is done through a public function (called registerAnimal for example) that takes for arguments a key (the animal name) and a pointer to the creation function for this type of animal. This register function must return something (a boolean for example), I'll explain why later.
Ok, so far, your factory is ready to be used. So now, how can we register our animals in the factory in a generic way ? That simple: in the source file of your class, add a global static member of the type returned by your register function of your factory (e.g. a boolean):
static bool bRegistered = CFactory::getInstance()->registerObject("Dog",CreateDog);
CAnimal* CreateDog()
{
return new CDog;
}
These static variables will be evaluated when your program start, and will invoke the registerObject function from your factory supplying your CreateDog function. So now, every animal is registered with your factory.
If you create a new animal type, just add these lines of code in your cpp file and the class will be registered automatically through your factory.
Hope this helped.
|
|
|
|
|
Nice solution but now you have to add 4 lines of code instead of two every time a new animal
is added?
|
|
|
|
|
Yes, but your code is much more maintainable: you have no dependcy at all between the different classes and the 'factory'. The factory only knows the base class. You can even do better by using a template factory so that you have a completely generic factory.
And also, whenever you add a new class to your architecture, the only thing you have to change is the file in which you have your class (which must be created).
|
|
|
|
|
Cedric Moonen wrote: Yes, but your code is much more maintainable
Yeah Just teasing! You could actually implement macros similar to MFC's
DECLARE_DYNCREATE/IMPLEMENT_DYNCREATE to make maintenance really simple.
|
|
|
|
|
Hi everyone,
I need to convert a unicode LPWSTR to multi-byte LPSTR .wcstombs _s doesn't do good,because it replaces non-english characters to their english likes (like ş->s and ı>i).
WideCharToMultiByte function seems to do this right,but the double-byte characters in the converted LPSTR are interpreted as if they are two single-byte characters.
to be more specific,I use MAPI dll to send an e-mail.MAPI dll expects all strings to be LPSTR which maps to int .but i want to use non-english characters in e-mail's body/subject/attached files' names,and couldn't find a solution yet.it's all good when strings are in english,because all unicode characters map to a signed char then.but when i get a non-english character,"problem".LPSTR seems to interpret all characters to be single-byte.
any suggestions?
|
|
|
|
|
ajitatif angajetor wrote: MAPI dll expects all strings to be LPSTR which maps to int.but i want to use non-english characters in e-mail's body/subject/attached files' names,and couldn't find a solution yet
What you need is encoding.
There are several types of encoding around, some standards, some more habits grown out of prolonged use.
Read about MIME.
"We trained hard, but it seemed that every time we were beginning to form up into teams we would be reorganised. I was to learn later in life that we tend to meet any new situation by reorganising: and a wonderful method it can be for creating the illusion of progress, while producing confusion, inefficiency and demoralisation."
-- Caius Petronius, Roman Consul, 66 A.D.
|
|
|
|
|
I have to support French for an application.
All the resources of my application are stored in a DLL for French. when select default language, main resource is loaded and if select french, french dll of resource is loaded. Everything is fine as long as no custom controls are used.
I get a problem with custom control when load resource dll:
In old version, there is a control which managed by ActiveX Control, when i load resource dll (french) -> DONE:
CONTROL "",IDC_PREF_DIALOG_HIST,
"{E41EAFC4-F536-11CF-93A1-0000C0A61E5A}",WS_TABSTOP,7,7,
397,114
But in new version, this control is edit to Custom Control and manage by a new class (CHistogramCtl). when I use default language (English) => OK. But when I use french language (resource DLL), I could not load dialog which contain this control.
CONTROL "Custom2",IDC_PREF_DIALOG_HIST,"Histogram_Ctrl_Class",
WS_TABSTOP,7,7,397,118,WS_EX_CLIENTEDGE
Any suggestion will be helpful.
Thanks in advance,
Papais
|
|
|
|