Click to See Complete Forum and Search --> : Lpctstr*
Clarke Kent
April 11th, 2003, 09:48 AM
A little confused by this.:confused: :confused:
Im receiveing this type as a parameter and it should contain names. The way i read it is its an array of pointers to a string.
LPCTSTR* names;
names[0] = "jack";
names[1] = "bob";
// is the above acceptable?
I think i just need a little tutorial on how to treat this type.
Thx.
PaulWendt
April 11th, 2003, 10:02 AM
What you really need to do is search through your compiler's
header files. If you do this, you'll probably find something like
this:
#define LPCTSTR const char*
Alright, it's not perfect, but it's good enough for our purposes.
So, no, what you typed is wrong. LPCTSTR is just a const char *.
LPCTSTR*, then, would be a char** ... but that doesn't actually
give you any memory or anything.
I think what you're trying to do is pass something to a function
that takes a LPCTSTR* as an argument, right? To do that, all
you need to do is create a two-dimensional array on the stack.
Then pass that array to the function.
Thx Paul. That helps.
Actually, what im doing is trying to parse this structure...
struct FOO{
int count
LPCTSTR* names;
LPCTSTR* addresses;
}
So im receiveing this structure from another module and i dont know how to deal with it.
Im trying to format it like so....
TCHAR names[5];
TCHAR address[5];
for( i = 0; i< foo.count; ++i ) {
names[i] = foo.names[i];
addresses[i] = foo.addresses[i];
}
...
// loop doing this
sprintf(buffer, "His name is %s and his address is %s.", names[i], addresses[i]);
I get messed up with strings.
Paul McKenzie
April 11th, 2003, 11:44 AM
Originally posted by Clarke Kent
Thx Paul. That helps.
Actually, what im doing is trying to parse this structure...
struct FOO{
int count
LPCTSTR* names;
LPCTSTR* addresses;
}
So im receiveing this structure from another module and i dont know how to deal with it.
Im trying to format it like so....
I'm under the assumption that you have control over the FOO structure, i.e. how it is defined.
The names and address TCHAR arrays are just that -- arrays of TCHAR. They are not pointers. In your loop, you are assigning a pointer value "foo.names[i]" to a single character, names[i]. This is incorrect. What you want to do is to copy all of the characters from foo.names[i] to the names character array (similarly with the address).
First, how long is each name? Is it a maximum of 4 characters (plus the NULL)? That is what your code suggests when you say names[5]. If you happen to have "Peter" as a name, you will be overwriting memory.
Second, I would have defined a single structure that takes one name and one address, and have an array of those. The problem with your code is that you're assuming that the number of names matches the number of addresses. In your loop, you may access a valid name, but an invalid address field, possibly causing a crash. This is of course if you can solidly, without a doubt, verify that for each name, there is an address and vice-versa.
But in general, the problem that I see is that string handling is too darn error prone and newcomers never have a comfortable time handling them. If you are coding in C++, you can relieve all of these problems by using std::string and std::vector instead of hard-coded arrays. Here is an example:
// First name and address
foo.name = "John";
foo.address = "123 Main Street";
// add it to vector
nalist.push_back( foo );
// Second name and address
foo.name = "Mary";
foo.address = "100 First Street";
nalist.push_back( foo );
// Third name -- note that the address is empty
foo.name = "A very long name of someone with no address";
nalist.push_back( foo );
WriteNames(nalist);
}
With the code above you've
a) solved the problem of having names and addresses of any size
b) Your arrays are not fixed sized, since you are not using arrays
c) solved the issue if there is no address that has been defined for a name, or vice-versa (since a std::string is "" if nothing has been defined).
If you are coding in 'C', then you have to make provisions (in other words, write more code) for things such as names of unlimited (or maximum length), making sure you check you don't access invalid memory, etc. The code I wrote above takes care of all of those details (which is why it is really hard to go back to C coding when you have C++ with all of its niceties :)
Regards,
Paul McKenzie
Yves M
April 11th, 2003, 11:58 AM
Just one note on LPCTSTR. As you have noted, it's a string of TCHARS, so depending on whether your code is compiled as Unicode or not, it will have two different meanings.
#ifdef _UNICODE
typedef wchar_t TCHAR;
// for some compilers / platforms it's actually typedef unsigned short TCHAR;
typedef const TCHAR *LPCTSTR;
#else
typedef char TCHAR;
typedef const TCHAR *LPCTSTR;
#endif
So, if you want to remain correct for both Unicode and ANSI versions of your program, you would have to use something like the following (assuming, TCHAR is properly defined for your compiler and operating system):
typedef std::basic_string<TCHAR> tstring;
Dmitry Zemskov
April 11th, 2003, 12:10 PM
Originally posted by Clarke Kent
... The way i read it is its an array of pointers to a string.
LPCTSTR* names;
names[0] = "jack";
names[1] = "bob";
// is the above acceptable?
Here is how you should have written what you wanted:
// In this case you may omit the array size
LPCTSTR names[] = { "jack", "bob" };
Morover, if you are not intended to modify the array you could make it static. In this case the latter example doesn't produce any code at all, while the former will still be initialized at run-time.
The code that PaulWendt suggested
char names[10][10] = {"jack", "bob"};
is a declaration/definition of two-dimensional array of arrays of ten chars each. That means despite "jack" is 4 chars long (plus 1 for tetminating zero), it will occupy 10 bytes anyway. The same thing with "bob" :-)
Clarke Kent
April 11th, 2003, 01:15 PM
This is all very helpful gentlemen, thank you; i really appreciate your time.
To clarify...
I'm under the assumption that you have control over the FOO structure, i.e. how it is defined
Let's assume i do not.
Then this is ok?
LPCTSTR* names = NULL;
LPCTSTR* addresses = NULL
for(i = 0; i < foo.count; i++){
_tcscpy( names, foo.names[i] );
_tcscpy( emails, foo.addresses[i] )
}
// loop
...
sprintf(buffer, "His name is %s and his address is %s.", names[i], addresses[i]);
Thx again!
Paul McKenzie
April 11th, 2003, 01:35 PM
Originally posted by Clarke Kent
This is all very helpful gentlemen, thank you; i really appreciate your time.
To clarify...
Let's assume i do not.
Then this is ok?
LPCTSTR* names = NULL;
LPCTSTR* addresses = NULL
for(i = 0; i < foo.count; i++){
_tcscpy( names, foo.names[i] );
_tcscpy( emails, foo.addresses[i] )
}
No this will not work. You are attempting to copy characters to NULL ponters. Your program will crash. The solution is what I posted, plus the caveats and potential problems in doing it the way I posted.
But you should seriously consider using std::string instead of these constructs.
Regards,
Paul McKenzie
PaulWendt
April 11th, 2003, 04:02 PM
Originally posted by Paul McKenzie
No this will not work. You are attempting to copy characters to NULL ponters. Your program will crash.
But you should seriously consider using std::string instead of these constructs.
Regards,
Paul McKenzie
No offense to the original poster, but in my opinion, you ought to
read up on pointers and arrays. Yeah, I'd suggest going "back
to basics" as it were. It's one thing to not know the value of a
#define; it's quite another to not understand something that's
so fundamental to the language. If you don't understand pointers
now, there is a lot you'll miss out on down the road. I suggest
you go through tutorials, take some classes, read some books, or
do whatever it is you need to in order to learn this stuff.
--Paul
Clarke Kent
April 14th, 2003, 08:41 AM
do whatever it is you need to in order to learn this stuff
What the he!! do you think im doing here?
Paul McKenzie
April 14th, 2003, 08:52 AM
Originally posted by Clarke Kent
What the he!! do you think im doing here? To be honest, you can't learn C++ by browsing or asking questions on a website. You must get books (and good ones) to learn the language correctly.
Regards,
Paul McKenzie
PaulWendt
April 14th, 2003, 09:05 AM
Originally posted by Clarke Kent
What the he!! do you think im doing here?
Yeah, similar to what Paul McKenzie said, we're not paid
instructors and I certainly don't have the time to give you
tutorials on the ins-and-outs of pointers. That is such a
basic part of the language, I think it's best if you learn it from a
textbook.
It's great to ask questions on here. What's not great is when one
question leads to another question, which leads to another
question, which leads ... etc. When stuff starts getting like that,
I start recommending books.
--Paul
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.