NO

Author Topic: Pointers problem  (Read 23713 times)

gromit

  • Guest
Pointers problem
« 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

gromit

  • Guest
Re: Pointers problem
« Reply #1 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

gromit

  • Guest
Re: Pointers problem
« Reply #2 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??

CommonTater

  • Guest
Re: Pointers problem
« Reply #3 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);
« Last Edit: June 05, 2012, 12:57:08 PM by CommonTater »

CommonTater

  • Guest
Re: Pointers problem
« Reply #4 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

« Last Edit: June 05, 2012, 01:07:12 PM by CommonTater »

migf1

  • Guest
Re: Pointers problem
« Reply #5 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!
« Last Edit: June 05, 2012, 05:12:35 PM by migf1 »

migf1

  • Guest
Re: Pointers problem
« Reply #6 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.

CommonTater

  • Guest
Re: Pointers problem
« Reply #7 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  

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.
 
« Last Edit: June 05, 2012, 04:44:09 PM by CommonTater »

migf1

  • Guest
Re: Pointers problem
« Reply #8 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  

I think _tcsncpy does the same (perhaps in a different way): 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!
« Last Edit: June 05, 2012, 05:13:31 PM by migf1 »

CommonTater

  • Guest
Re: Pointers problem
« Reply #9 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...

gromit

  • Guest
Re: Pointers problem
« Reply #10 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

CommonTater

  • Guest
Re: Pointers problem
« Reply #11 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...




gromit

  • Guest
Re: Pointers problem
« Reply #12 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 ?

CommonTater

  • Guest
Re: Pointers problem
« Reply #13 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.


CommonTater

  • Guest
Re: Pointers problem
« Reply #14 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

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...