Pelles C forum

C language => Pocket PC and Smartphone questions => Topic started by: gromit on June 05, 2012, 11:17:12 AM

Title: Pointers problem
Post by: gromit on June 05, 2012, 11:17:12 AM
wchar_t  *ptrstrold=L"X";
wchar_t  *ptrstrnew=L"X";   
GetDlgItemText(hDlg, UNIT_STATIC,ptrstrold,len+1); // got text from static control

GetDlgItemText(hDlg, UNIT_QTY_COMBO,ptrstrnew,len+1);   // got text from qty combo

e.g
static control text = "1 No widget"
UNIT_QTY_COMBO text = "5"
I want ptrstrnew to read    "5 No widget"

 if i + 1 on ptrstrold i am left with " No widget"

how do i add ptrstrold to ptrstrnew to give result ptrstrnew = "5 No widget"
i know i could do it with strings but i would like to understand pointers more.

Sorry if its obvious
but at the moment not to me...... :-[
BTIA Gromit
Title: Re: Pointers problem
Post by: gromit on June 05, 2012, 12:33:26 PM
i now find some curiosity in this
concentrating on ptrstrold only
ptrstrold=ptrstrold+sizeof(wchar_t)*1 results in an empty string when i try to print ptrstrold
ptrstrold=ptrstrold+1 results in an empty string
ptrstrold=ptrstrold+4 and ptrstrold=ptrstrold+sizeof(wchar_t)*4
both result in the string minus the the first four characters
i only want to lose the first 1 or 2 ???
Doh
Title: Re: Pointers problem
Post by: gromit on June 05, 2012, 12:45:57 PM
Just got to come back on this
ptrstrold=ptrstrold+3 or 2 or 1 results in an empty string
ptrstrold=ptrstrold+ 4 or more knocks off the front of the string 4 or more characters

so ptrstrold=ptrstrold+ 4 results in "Four/Characters" becoming "/characters"
But
ptrstrold=ptrstrold+ 3 or less results in "Four/Characters" becoming an empty string
I am printing string in windows Messagebox so i will check its not that misinterpreting the string??
Title: Re: Pointers problem
Post by: CommonTater on June 05, 2012, 12:52:03 PM
wchar_t  *ptrstrold=L"X";
wchar_t  *ptrstrnew=L"X";   
GetDlgItemText(hDlg, UNIT_STATIC,ptrstrold,len+1); // got text from static control

GetDlgItemText(hDlg, UNIT_QTY_COMBO,ptrstrnew,len+1);   // got text from qty combo

That's not going to work.  If you are going to work with wchar_t* you need to allocate memory to hold the strings you get from your dialogs, and you will need to free() that memory when you're done with it...
Code: [Select]
// plan a - string buffer
#define MAX_BUF 128
 
wchar_t* buffer = malloc(MAX_BUF * sizeof(wchar_t));
 
GetDlgItemText(hDlg, Unit_Static, buffer, MAX_BUF);
...
free(buffer);
 
 
// plan b - exact size
int size = GetWindowTextLength(GetDlgItem(hDlg,Unit_Static));
wchar_t* exact = malloc((size * sizeof(wchar_t)) + sizeof(wchar_t));
 
GetDlgItemText(hDlg, Unit_Static, exact, size);
...
free(exact);
Writing over unallocated memory puts your system at risk... you may overwrite other variables, other variables may overwrite your stuff... or you might crash your program outright. It's the same as in the real world... If you don't own it, it's not yours to take.
 
Quote
how do i add ptrstrold to ptrstrnew to give result ptrstrnew = "5 No widget"
i know i could do it with strings but i would like to understand pointers more.

You're going to have to do this with string manipulations.  If you try to "trick it out" in a single buffer by putting in the 1 No widget" first then overwriting the first part of the string with the 5, you're going to run into troubles with the trailing null on the second string.  The only way you could get away with it is if you know for absolutely certain the data from the combobox will only ever be a single digit... then you could use  control_buffer[0] = static_text[0] to copy the first character.
 
Now if you didn't have the 1 at the beginning of the string from the static control, you could do something like this...
Code: [Select]
#define MAX_BUF 32  // bigger than you'll need!
 
// create your buffer
wchar_t* string1 = calloc(MAX_BUF, sizeof(wchar_t));
wchar_t* string2 = string1;
// get the first text bit
GetDlgItemText(hDlg,COMBO,string1,MAX_BUF);
// find the end of the first string
while(*string2++);
// get the second text bit
GetDlgItemText(hDlg,STATIC,string2,MAX_BUF - wcslen(string1));
 
...
free(string1);
Title: Re: Pointers problem
Post by: CommonTater on June 05, 2012, 12:58:58 PM
i now find some curiosity in this
concentrating on ptrstrold only
ptrstrold=ptrstrold+sizeof(wchar_t)*1 results in an empty string when i try to print ptrstrold
ptrstrold=ptrstrold+1 results in an empty string
ptrstrold=ptrstrold+4 and ptrstrold=ptrstrold+sizeof(wchar_t)*4
both result in the string minus the the first four characters
i only want to lose the first 1 or 2 ???
Doh

This does not work because you have not allocated any memory to the string... all you're doing is adding a number to an uninitialized pointer... which could have any random value in it.
 
Moreover; if you did allocate memory with malloc() or calloc(), disturbing the "root pointer" (the address of the memory buffer) will cause free() to fail and your program would leak memory.
 
Give this a read... http://pw1.netcom.com/~tjensen/ptr/pointers.htm (http://pw1.netcom.com/~tjensen/ptr/pointers.htm)

Title: Re: Pointers problem
Post by: migf1 on June 05, 2012, 04:01:47 PM
May be a bit off-topic, but you can also consider using the win32api-specific TCHAR data type instead of char/w_char, along with the _T() / TEXT() macro, and use the win32api generic string functions. This simplifies things and makes your programs "unicode ready" (just #define _UNICODE and UNICODE before anything else) .

For example...

Code: [Select]
#include <tchar.h>
...
#define my_strncpy    _tcsncpy   // generic win32api function for strncpy (I'm just defining a more familiar name for it)
#define MAX_BUF  (255+1)
...
TCHAR  *ptrstrold = NULL;
TCHAR  strnew[ MAX_BUF] = {TEXT('\0')};   // this makes sure strnew is padded with 0s
...
// read old text
if ( NULL == (ptrstrold = malloc(MAX_BUF * sizeof(TCHAR)) )
    // handle failure here
if ( 0 == GetDlgItemText(hDlg, Unit_Static, ptrstrold , MAX_BUF) )
    // handle failure here
free( ptrstrold );

// assign new text
my_strncpy( strnew, TEXT("I'm the new string"), MAX_BUF-1 );  // padded initialization comes handy here
if ( 0 == SetDlgItemText(hDlg, Unit_Static, strnew) )
    // handle failure here

...

EDIT:
Lots of typos!
Title: Re: Pointers problem
Post by: migf1 on June 05, 2012, 04:15:18 PM
Sorry about that, but I had a bunch of typos in the code above, which rendered it useless. I fixed them now.
Title: Re: Pointers problem
Post by: CommonTater on June 05, 2012, 04:21:15 PM
May be a bit off-topic, but you can also consider using the win32api-specific TCHAR data type instead of char/w_char, along with the _T() / TEXT() macro, and use the win32api generic string functions. This simplifies things and makes your programs "unicode ready" (just #define _UNICODE and UNICODE before anything else) .

TCHARs are good.  But, since practically nobody writes ANSI code anymore (it's all unicode) he can also use the windows WCHAR and PWCHAR types ... In general my habit to use Windows types when working GUI code and C types when in console mode.   

Just a couple of points, if I may...

Code: [Select]
#include <tchar.h>
...
#define my_strncpy    _tcsncpy   

Actually the winapi function is lstrcpy() which switches modes with the unicode define.
 
Windows API defines a whole set of them...  HERE (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646979(v=vs.85).aspx) 

Code: [Select]
TCHAR  strnew[ MAX_BUF] = TEXT("\0");   // this makes sure strnew is padded with 0s
Actually that just writes a NULL in the first character position. 
If you want an all 0 string...
Code: [Select]
TCHAR strnew[MAX_BUF] = {0};  // on the stack
or
PTCHAR strnew = calloc(MAX_BUF,sizeof(TCHAR));  // on the heap

 EDIT: Found a better link for the string functions.
 
Title: Re: Pointers problem
Post by: migf1 on June 05, 2012, 05:10:55 PM
...
TCHARs are good.  But, since practically nobody writes ANSI code anymore (it's all unicode) he can also use the windows WCHAR and PWCHAR types ... In general my habit to use Windows types when working GUI code and C types when in console mode.

Personally I find it quite handy to use just one interface for both GUI and Console apps. It makes things much more simpler for me, especially in maintaining the code of several projects.

That being said, I don't consider myself an expert in the Win32 API, so your suggestion may very well be a better approach, having certain advantages I'm not aware of.

Quote
Just a couple of points, if I may...

Sure!

Quote
Code: [Select]
#include <tchar.h>
...
#define my_strncpy    _tcsncpy   

Actually the winapi function is lstrcpy() which switches modes with the unicode define.
Windows API defines a whole set of them...  HERE (http://msdn.microsoft.com/en-us/library/windows/desktop/ms646979%28v=vs.85%29.aspx) 

I think _tcsncpy does the same (perhaps in a different way): http://msdn.microsoft.com/en-us/library/xdsywd25%28v=vs.80%29.aspx (http://msdn.microsoft.com/en-us/library/xdsywd25%28v=vs.80%29.aspx)

Quote
Code: [Select]
TCHAR  strnew[ MAX_BUF] = TEXT("\0");   // this makes sure strnew is padded with 0s
Actually that just writes a NULL in the first character position. 
If you want an all 0 string...
Code: [Select]
TCHAR strnew[MAX_BUF] = {0};  // on the stack
or
PTCHAR strnew = calloc(MAX_BUF,sizeof(TCHAR));  // on the heap

That was one of the typos I fixed a bit later. The fixed one was wrong too :lol: Ι just fixed it again, so now it does pad strnew with 0s during initialization.

Btw, I'm still missing (later on) a line before: free(), meaning it should read something like this ...

Code: [Select]
if ( 0 == GetDlgItemText(hDlg, Unit_Static, ptrstrold , MAX_BUF) )
    // handle failure here
// do whatever you need to do with ptstrold here, then free it
free( ptrstrold );
...

PS. Thanks for the link!
Title: Re: Pointers problem
Post by: CommonTater on June 05, 2012, 08:34:00 PM
Personally I find it quite handy to use just one interface for both GUI and Console apps. It makes things much more simpler for me, especially in maintaining the code of several projects.

The reason I use windows types instead of crt types is that some of them are not exactly the crt "equivalents" and some accomodate x64.  It's more specific which, in my experience, usually means better...

Quote
That being said, I don't consider myself an expert in the Win32 API,

Nor do I...

Quote
PS. Thanks for the link!

No worries...
Title: Re: Pointers problem
Post by: gromit on June 05, 2012, 08:38:05 PM
Thanks for your input everybody

 I have learnt a fair bit there.
I am grateful

I have however for the second time in 2 years
Had A main.c file wiped clean .
It was 137 k of code and when i went back to it from this forum earlier
It is now 137 k of zeros  :o :o :o :o
Are there any limits to size of main.c ?

Anyone else experienced that???

Once again Big Thanks Gromit
Title: Re: Pointers problem
Post by: CommonTater on June 05, 2012, 08:41:43 PM
I have however for the second time in 2 years
Had A main.c file wiped clean .

I've had that a couple of times too... I believe, without knowing for certain, that it happens when you exit POIDE with unsaved files in memory.  If you can track down the cause, in a repeatable way, you should make a bug report for Pelle...



Title: Re: Pointers problem
Post by: gromit on June 06, 2012, 12:59:43 AM
Hi Tater
Glad i am not the only one losing files
Fortunately i had a fairly recent backup.

Were the files you lost very large ?
Title: Re: Pointers problem
Post by: CommonTater on June 06, 2012, 02:31:29 AM
Hi Tater
Glad i am not the only one losing files
Fortunately i had a fairly recent backup.

Were the files you lost very large ?


Not really, I tend to break things up in some way that feels right for each project, so I end up with multiple smaller files and like you I keep frequent backups, sometimes hourly while working.

Title: Re: Pointers problem
Post by: CommonTater on June 06, 2012, 05:46:04 PM
I think _tcsncpy does the same (perhaps in a different way): http://msdn.microsoft.com/en-us/library/xdsywd25%28v=vs.80%29.aspx (http://msdn.microsoft.com/en-us/library/xdsywd25%28v=vs.80%29.aspx)

I just followed your link... Small problem... _tsncpy() does not even exist in Pelles C runtime library.  They are C++ runtime library functions...

You need to be careful with using Microsoft's C++ library references with Pelles C... they're not the same language and, in many cases, they're not compatible. 

The ultimate authority on Pelles C is it's own help file... you should always check CRT functions there before recommending them.

Also note that the Windows headers and libs supplied with Pelles C are not exactly Microsoft's versions.  They have been modified to use Pelles C's base variable types, etc.  So it's often best to check those against the supplied headers as well...
Title: Re: Pointers problem
Post by: migf1 on June 06, 2012, 07:58:16 PM
That's weird. It compiles and runs fine for me (both on XP 32-bit and 7 64-bit) with v 6.50.
Title: Re: Pointers problem
Post by: CommonTater on June 06, 2012, 08:20:26 PM
Yes.. it is weird...

_tcsncpy is there and it does compile and work...  turns out, its in the tchar.h private header.

But it's not indexed in the help file...

In any case it is clearly labled as "Not Standard C" in which case you cannot expect it to work on any other compiler or run time library... Thus, not portable.

Title: Re: Pointers problem
Post by: migf1 on June 06, 2012, 08:30:32 PM
Actually, it does compile & runs fine with both pelles c and mingw32 (the latter means it also works fine with VC++, since they share the same runtime).

PS. Of course it's not a standard C function, it's a win32api specific extension, as is the rest of the context I used it, in the original post.
Title: Re: Pointers problem
Post by: CommonTater on June 06, 2012, 08:34:21 PM
PS. Of course it's not a standard C function, it's a win32api specific extension, as is the rest of the context I used it, in the original post.

Actually not... it's a C++ function that's (apparently) been adopted in to Pelles C... as you point out it works in Mingw since it uses the VC++ runtimes. The actual Windows API documentation does not list it but provides, instead, the functions I linked to.
 
(And now I need an aspirin  :o  )



 
Title: Re: Pointers problem
Post by: migf1 on June 06, 2012, 09:29:55 PM
To be precise, it's a Microsoft extension (as are all the TCHAR generic functions, also known as Generic Text Mappings) and that explains why it is also supported in Pelles C ;)

[offtopic]
Quote
(And now I need an aspirin  (http://forum.pellesc.de/Smileys/default/shocked.gif)  )
:lol:

To be totally honest, programming the Win32 API using C these days is dangerously flirting with... masochism. I admit I'm a bit of a masochist myself, mostly because I love the C language.

But realistically, very few people do it any more... and even more fewer are likely to keep doing it. Most people use .net for such tasks (what a bloatware!), and the rest are using any of the several C++ wrappers available.

Have you ever tried GTK+? Well, it blows the Win32 API away, and it's also a core C GUI framework.

At first it may seem a bit of a pain to set it up for Windows, but it is actually not. Setting up a gcc toolchain to go along with GTK+ may be a bit more challenging, but nothing difficult really.

Anyway, a while back in my effort to refresh my GTK+ skills (after a very long sabbatical ... that translates to 3-4 years :lol:) I wrote a little tic-tac-toe game with GTK+2 on Windows and if my memory serves me well, I was also compiled it with Pelles C (along with mingw32).

I can try to find it and post it, if anyone is interested in having a look at it.

It's a pitty that GTK+3 is not available for Windows though... it is left in v 2.28, while its Posix counterpart is already in v 3.4+ Same thing for Glade :(

Still, I find it much more fun (and productive) than Win32.

[/offtopic]
Title: Re: Pointers problem
Post by: CommonTater on June 06, 2012, 10:51:51 PM
To be precise, it's a Microsoft extension (as are all the TCHAR generic functions, also known as Generic Text Mappings) and that explains why it is also supported in Pelles C ;)

Ok... what I meant was that it's an extension to C++ ... but the Windows API doesn't mention it. 
In any case, it's not standard Pelles C, C-11 or C-99 so recommending it requires some precaution.

Quote
To be totally honest, programming the Win32 API using C these days is dangerously flirting with... masochism. I admit I'm a bit of a masochist myself, mostly because I love the C language.

But realistically, very few people do it any more... and even more fewer are likely to keep doing it. Most people use .net for such tasks (what a bloatware!), and the rest are using any of the several C++ wrappers available.

I'm an electronics tech, trainee and trainer back in the day when you could actually fix stuff... I got really good at it too.  But that's because I'm a "nuts and bolts" sort of person who likes to get right into things at the most basic levels... This of course makes C a natural for me, short of going to pure ASM (which has been contemplated) C is about as close to the metal as I can get... and that suits me just fine.

I have tried C++ with GTK and wsWidgets too.. hated it, just plain hated it...  Now if only I could get my hands on a proper Pascal implementation with x64, unicode and Windows API units...  8)   8)   8)  ... but from what I can find it's not out there.  Free Pascal is as close as it gets and to be honest it's such a dog's breakfast I would need *years* to get it into useable condition.