473,224 Members | 1,480 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,224 software developers and data experts.

Dodgy string conversion (please help)

I am new to VC++7. I am using a method GetPrivateProfileString that
requires an LPTSTR.
I have defined this as a:

char * data_name;

I am then trying to convert this to an LPOLESTR and I have done this as
follows:

LPOLESTR dunk_data = (LPOLESTR)T2CW(data_name);

However this is in a loop and data_name always contains the correct string
but dunk_data sometimes contains the correct data and sometimes loads of
Chinese or Arabic characters also/instead.

Something is dodgy, please can someone point me in the right direction???

thanks,

Duncan
Nov 16 '05 #1
8 4308
> I am new to VC++7. I am using a method GetPrivateProfileString that
requires an LPTSTR.
I have defined this as a:

char * data_name;

I am then trying to convert this to an LPOLESTR and I have done this as
follows:

LPOLESTR dunk_data = (LPOLESTR)T2CW(data_name);

However this is in a loop and data_name always contains the correct string
but dunk_data sometimes contains the correct data and sometimes loads of
Chinese or Arabic characters also/instead.

Something is dodgy, please can someone point me in the right direction???


You need to read up on TCHARs and generic text programming in general. First
of all, your conversion should be:

LPTSTR dunk_data = A2T(data_name);
or
LPCTSTR dunk_data = A2CT(data_name)

depending on what you're using this for (non-const or const string). Also,
you don't need LPOLESTR from what I see, assuming this is for
"GetPrivateProfileString()" (OLESTR buffers and pointers are for COM work).
More importantly, just define "data_name" as a TCHAR instead of "char" and
you won't need this conversion at all. In fact, this is how you should
normaly define all your (character/string) buffers unless you're always
targetting an ASCII or Unicode build exclusively (and never the other). This
will all become clear once you read up on the subject though follow-up
questions will be likely (it can be confusing at first). Note that ASCII
builds are becoming less and less relevant as everything moves to Unicode
anyway so it's less of an issue now. IOW, you can also choose to use
"wchar_t" directly instead of TCHAR if your app will *always* be targetted
for an NT-based OS (NT, 2000, XP and beyond). These OSs work in Unicode
under the hood but the whole topic is deeper than I can get into here (you
may be a little lost by now). BTW, for those times when you do need the ATL
conversion macros as above (sometimes you do), don't generally call them
directly inside of loops. They allocate space on the stack which grows on
each iteration until you can have a potential stack overflow problem. If you
need to do this then invoke a (possibly inlined) function inside your loop
instead (which calls the ATL conversion macro and therefore frees the space
automatically on each iteration).
Nov 16 '05 #2
Duncan Winn wrote:
I am new to VC++7. I am using a method GetPrivateProfileString that
requires an LPTSTR.
I have defined this as a:

char * data_name;

I am then trying to convert this to an LPOLESTR and I have done this as
follows:

LPOLESTR dunk_data = (LPOLESTR)T2CW(data_name);

However this is in a loop and data_name always contains the correct string
but dunk_data sometimes contains the correct data and sometimes loads of
Chinese or Arabic characters also/instead.

Something is dodgy, please can someone point me in the right direction???

thanks,

Duncan


I hit a problem like that a while ago
If I remember correctly those conversion macros can be dangerous to use
in loops since they allocate memory on the stack in a special way (can't
remember the exact details) and this can lead to memory corruption

Try put the code containing the call to T2CW() in a separate function

so you should have something like
for()
{
fn();
}

and the function can not be inline

Vin

Nov 16 '05 #3
"Duncan Winn" <te**@test1.co.uk> wrote in message
news:u$**************@TK2MSFTNGP10.phx.gbl...
I am new to VC++7. I am using a method GetPrivateProfileString that
requires an LPTSTR.
I have defined this as a:

char * data_name;

I am then trying to convert this to an LPOLESTR and I have done this as
follows:

LPOLESTR dunk_data = (LPOLESTR)T2CW(data_name);

However this is in a loop and data_name always contains the correct string
but dunk_data sometimes contains the correct data and sometimes loads of
Chinese or Arabic characters also/instead.

Something is dodgy, please can someone point me in the right direction???


AFAIK, you are not supposed to use the string conversion macros in a loop.
That might be the problem. Another thing is that a char* is not necessarily
the same thing as a TCHAR*. That might be the problem too. How do you
initialize and/or use 'data_name'? Also, why not try the T2COLE macro
instead of casting T2CW?

Jeff...
Nov 16 '05 #4
Thanks John.....

To clarify..... I am using GetPrivateProfileString so I have now defined a
'TCHAR * data_name' and used it asfollows:

GetPrivateProfileString (section_name, field_name, "", data_name, 256,
"C:\ini22.ini");

This works and gives me the correct result! However I am then trying to use
the result in COM by calling a method in an OLE DB provider that requires an
LPOLESTR. I have tried to convert my TCHAR as follows:
_rgColumns[ulCols].pwszName = (LPOLESTR)(T2COLE(data_name)); // and also
T2OLE

But this give me the strange results as sometimes the output is correct and
other times not????

Any further suggestions? I have tried using wchar_t but it did not give
anything meaningful from the GetPrivateProfileString??
Nov 16 '05 #5
> To clarify..... I am using GetPrivateProfileString so I have now defined
a
'TCHAR * data_name' and used it asfollows:

GetPrivateProfileString (section_name, field_name, "", data_name, 256,
"C:\ini22.ini");

This works and gives me the correct result! However I am then trying to use the result in COM by calling a method in an OLE DB provider that requires an LPOLESTR. I have tried to convert my TCHAR as follows:
_rgColumns[ulCols].pwszName = (LPOLESTR)(T2COLE(data_name)); // and also
T2OLE

But this give me the strange results as sometimes the output is correct and other times not????

Any further suggestions? I have tried using wchar_t but it did not give
anything meaningful from the GetPrivateProfileString??


First of all, you need to understand all these string types which I can't
fully explain here. Quick summary only: In Windows, all the args you pass to
"GetPrivateProfileString()" and most other WinAPI functions need to be TCHAR
based. Search MSDN for both "Generic Text Mappings" and also see technical
article "TN059" (for starters). In a nutshell, when you compile your app,
all occurrences of TCHAR are changed to "char" if the constants _UNICODE and
UNICODE are *not* #defined or "wchar_t" if they are #defined (the reason for
both #defined constants is another topic). This way, you can create a
Unicode build or an ASCII build simply by #defining these constants or not
at compile time (respectively). So, TCHAR is nothing more than "char" or
"wchar_t" depending on the presence of these #defined constants. Note that
if your app is targetted for WinNT or beyond then you should normally
#define both constants since WinNT works with Unicode under the hood. Your
app will therefore run more efficiently (you can read up on the subject but
the info is widely dispersed).

Now, understand that LPTSTR is simply a pointer to a non-const TCHAR based
string. LPCTSTR (note the added 'C') is a pointer to const TCHAR-based
string. IOW, if the #defined Unicode constants I described above are *not*
present, LPTSTR simply maps to "char *" and LPCTSTR maps to "const char *".
If those Unicode constants *are* #defined however, then LPTSTR maps to
"wchar_t *" and LPCTSTR maps to "const wchar_t *".

All WinAPI functions where you see either LPTSTR or LPCTSTR therefore need
to be passed TCHAR strings only (watch our for some rare functions that take
pure ASCII or Unicode arguments however - these will be LPSTR, LPCSTR,
LPWSTR or LPCWSTR). Most functions work with TCHAR however so you must pass
TCHAR args. String literals for instance should therefore be surrounded
with the _T macro (note that there are other variations on this macro's name
I won't get into here - they all do the same thing). A string like
"C:\\ini22.ini" should therefore be passed as _T("C:\\ini22.ini") instead
(also note the double backslash I added to the string - your original
example doesn't have this but it must - read up on "escape sequences"). The
_T macro simply ensures the string is either ASCII or Unicode accordingly
(by prepending an "L" in front of your string as required - you can read up
on this macro).

Finally, note that all ASCII-based (C-runtime) string functions you would
normally call such as "strcpy()" need to be replaced with their TCHAR
equivalent ("_tcscpy()" in this case). Search by title for "Routine
Mappings" in MSDN.

Now, an LPOLESTR is a different beast. It's actually a string of OLECHARs so
LPOLESTR is simply "OLECHAR *" and LPCOLESTR is a "const OLECHAR *". An
OLECHAR is the character used by COM on the host OS which is simply
"wchar_t" in Win32. So OLECHAR is really a "wchar_t" on all modern versions
of Windows but it should be treated as if it were a real type (OLECHAR, not
"wchar_t"). You can convert from a TCHAR string to an OLECHAR string by
using T2OLE or T2COLE (non-const and const versions). Therefore, your call
should appear as:

_rgColumns[ulCols].pwszName = T2OLE(data_name);

This assumes that "_rgColumns[ulCols].pwszName" is defined as an LPOLESTR,
which presumably it is since you're apparently using it to call an OLE DB
function that takes this (BTW, ADO is typically much easier than using OLE
DB directly). Anyway, the conversion should work correctly assuming you're
following all the rules I've described. If you are and something is still
amiss then something else is causing your problem.

Lastly, note that the "" you're passing as the 3rd arg to
"GetPrivateProfileString()" , which should actually be _T("") as per the
above discussion, may cause an unrelated problem. If an empty string is
returned in "data_name", you can't tell whether your "field_name" is either
missing or simply isn't assigned a value (I'd have to double check and it
may not be an issue for you anway).
Nov 16 '05 #6
Hi, thanks alot, that makes everything a bit clearer. My main problem still
is that in my loop I am defining a
LPWSTR tester;

and for some reason it uses the same bit of memory every time it loops, thus
overwriting the previous contents? I am not sure the best way to copy this
information? Any ideas?? All my other conversions seem to work fine!
Nov 16 '05 #7
> Hi, thanks alot, that makes everything a bit clearer. My main problem
still
is that in my loop I am defining a
LPWSTR tester;

and for some reason it uses the same bit of memory every time it loops, thus overwriting the previous contents? I am not sure the best way to copy this information? Any ideas?? All my other conversions seem to work fine!


I'm not quite sure what you mean now. If this is defined inside the loop
itself then you can't rely on its value between iterations because "tester"
goes of scope on each iteration. IOW, it's re-created each time the loop
starts so its inital value will be random until you initialize it to
something again. Define it outside the loop and you'll be ok (assuming this
what you're alluding to - post the relevant code otherwise).
Nov 16 '05 #8
Thanks for all the help John,

It is all done now!
Nov 16 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: John van Terheijden | last post by:
Hi. I'm trying to make a conversion algorithm that colors even and odd words in a HTML string with <div> tags. // input text with all sorts of HTML tags and whitespace $str = "<h1>Title...
2
by: Thomas Matthews | last post by:
Hi, I'm working with Borland C++ Builder 6.2. My project uses the std::string class. However, Borland in its infinite wisdom has its own string class, AnsiString. To make my life easier, I...
7
by: john | last post by:
On my form i have a message box called txtItemDesc that displays the french phrase qualité Père Noël. Now then when i run this code on that text box: Dim chrArr() As Char chrArr =...
6
by: LCD | last post by:
This a rather simple question for all you studs out there! Please help me with this. I have a string = "Please help me", and I want to convert this into it's hex equivalent. How do I do it, I...
5
by: Lonewolf | last post by:
Hi, I'm not sure if this has been asked before so please pardon me if this is a repeated question. Basically I have some performance critical directshow codes which is implemented in native,...
8
by: Toms | last post by:
This won't compile for me, it's saying "wcslen" isn't defined in the "std" namespace: #include <cwchar> int main() { std::wcslen("monkey"); }
2
by: voidtwerp | last post by:
Hi, showing my extreme ignorance I would like comments how the char arrays are used here, ie are these valid or dangerous uses (the reason I ask is because constructs like these occur in some...
6
by: tommaso.gastaldi | last post by:
Hi, does anybody know a speedy analog of IsNumeric() to check for strings/chars. I would like to check if an Object can be treated as a string before using a Cstr(), clearly avoiding the time...
3
by: Kevin Frey | last post by:
I am porting Managed C++ code from VS2003 to VS2005. Therefore adopting the new C++/CLI syntax rather than /clr:oldSyntax. Much of our managed code is concerned with interfacing to native C++...
1
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.