|
Two problems:
1) pchar is an array of char*, not char. So you will not be able to access the elements in the pchar array as a string. Which means that you will not be able to send that array to strcpy.
What you would actually do with an array like pchar is point to 6 different strings. Then when you wanted to use one of the strings you would access the string in the array like so:
strcpy(pchar[0], ...);
2) character is a char array, which is equivalent to one char*. Therefore you do not need to take the address of the character array, you could directly pass it into strcpy like this:
strcpy(..., character);
Good Luck
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
but i want to point to character, if i dake the address (&) off, it wouldnt be point to character would it?
so i would have to declare my pchar like
char *pchar[6];
pchar[0] = &character[0];
pchar[1] = &character[1];
pchar[2] = &character[2];
pchar[3] = &character[3];
pchar[4] = &character[4];
pchar[5] = &character[5];
?
i hope thats wrong... thats allot to type for somthing so small
Thank!
~SilverShalkin
|
|
|
|
|
Lets assume for a minute that you did do that.
You could then do this:
printf("%s\n",pchar[0]);
printf("%s\n",pchar[1]);
printf("%s\n",pchar[2]);
printf("%s\n",pchar[3]);
printf("%s\n",pchar[4]);
printf("%s\n",pchar[5]);
and the results would be:
hello
ello
llo
lo
o
<<there would="" be="" a="" blank="" line="" here="">>
in summary an array of characters IS a pointer to a sequence of characters.
so if we were to do this instead
char characters[6] = "hello";
char* pchar = characters;
char* pchars = &characters[0];
then examine the values of all three variables in the debugger.
they would all be identical.
Hope this helps in your struggle with pointers.
Roger.
|
|
|
|
|
Do this instead :-
char *pchar;
char abc[6];
strcpy(abc,"hello");
pchar = abc;
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
would that work? - ill insert some of the code replies and try to understand this more... thanks guys!
~SilverShalkin
|
|
|
|
|
SilverShalkin wrote:
would that work?
Of course, it will work
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
WARNING: This is a long post.
I think your real problem here is a misunderstanding of how C style pointers work and how to use them. Let me start by saying that a pointer is an intrinisic data type just like float, int, char, etc. The pointer data type (on Win32 systems) is a 32 bit value. This means that when you write a statement like
void* pSomeValue;
you are telling the compiler to allocate 32 bits of memory for your program. It also identifies that you intend to populate that variable with a memory address. In the case of a void type pointer you are saying that the memory pointed to by the variable can be of any type you want. (In other words, no type affinity.)
C and C++ allows pointers to have type affinity also. This means that instead of being a void pointer, you can define a pointer like
char* pszSomeValue;
OR
long* plSomeValue;
OR
CSomeClassName* pSomeValue;
ETC.
When you define a pointer like this you are telling the compiler that you want it to allocate 32 bits of storabe for a variable that will eventually point to a specific data type (char, long, CSomeClassName).
The next subject of confusion (I think) is when you are using C style arrays of a particular data type. In your example, you used char* pchar[6] and char character[6] = "hello".
The char* pchar[6] is instructing the compiler to allocate 6 memory locations each having a type affinity for a pointer to a char. This means that the compiler will allocate six 32 bit memory locations whose values it expects to be pointers to a char (char*).
The char character[6] is instructing the compiler to allocate 6 memory locations each having a type affinity for a char (NOT a pointer to a char). This means that the compiler will allocate six 8 bit memory locations (that is the size of a char data type) whose value it expects to be a char.
One of the nuiansces of C style arrays is that when you allocate a C style array the compiler guarantees that the memory it allocates will be continuous. This means that when you do char *pchar[6];, the compiler is going to allocate 32*6 bits in a row. When you do char character[6], the compiler is going to allocate 8*6 bits in a row.
OK. That was a long winded explanation of pointers and arrays. With that understanding, lets look at the line of code where the compiler is giving you a problem.
strcpy(pchar, &character);
The strcpy function is defined as taking 2 paramaters, a char* and a const char*. (Ignore the const for now.) The second parameter is supposed to be a pointer to an array of characters with the last character being NULL (NULL terminated string.) The first parameter is supposed to be a pointer to an array of characters large enough to contain the data pointed to by the second parameter. (BYW strcpy will copy the contents of the second parameter to the first, therefore you will have 2 seperate copies of the data. Changing one will not affect the other.)
For the first parameter, you are passing in a an array of char* type pointers. This is quite different from an array of char type. (Remember char* = 32 bits, char = 8 bits.) As you can see, for the first parameter, the compiler is confused because it is expecting the char array, not the char* array.
You say "what i am trying to do is, have pchar point to the address of character". If this is really what you want, then what you would want to write is
char *pchar;
char character[6] = "hello";
pChar = character;
You may be thinking "how can I assign an array to a pointer?". The answer to this obvious questions goes back to the previous explanation or how C style arrays work. When you specicify the variable name of a C style array without specifying an index into the array (ie. character instead of character[0]), the compiler knows that you want a pointer to the array.
I hope this helps more that it confuses.
|
|
|
|
|
it helps allot, thank you for spending the amount of time that it took to type that long thing I know how pointers and stuff work, its just, there are a couple of things that are in the gray, as in (I dont know if it will do the exact thing i want it)
i guess i should use strcpy() for a pointer, "it doesnt make sense to do so "
i think i should print this out...
Thanks for your time!
~SilverShalkin
|
|
|
|
|
Strange...
(not picking on you redeemer)
Tim Smith
I know what you're thinking punk, you're thinking did he spell check this document? Well, to tell you the truth I kinda forgot myself in all this excitement. But being this here's CodeProject, the most powerful forums in the world and would blow your head clean off, you've got to ask yourself one question, Do I feel lucky? Well do ya punk?
|
|
|
|
|
did you spell check that?
~SilverShalkin
|
|
|
|
|
Tim Smith wrote:
not picking on you redeemer
Then, who else are ya picking on?
Moi???
Nish
Regards,
Nish
Native CPian.
Born and brought up on CP.
With the CP blood in him.
|
|
|
|
|
i have a picture box controls on a dialog box.i want to show bitmap on it, on the click event of another dialog. doing so causes DEBUG ASSERTION FAILED! msg first and then image iz displayed on the top left corner of screen instead of picture box. i m trying to solve the problem for the last two weeks but didnt find any solution.
(if i use the device context of Dialog instead of picture box then it works well but when i try to get the device context of picture box it don't.)
if u know something about this problem or have some helping code plz give it to me. thanx
God Helps those who help others.
|
|
|
|
|
Can't quite figure that out yet...
THanks
|
|
|
|
|
NM_RCLICK doesn't work?
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
Yes, and then create a
NMLISTVIEW *pNmlv;
and assign the value of lParam to it
pNmlv = (NMLISTVIEW *)lParam;
and
if (pNmlv->iItem == -1)
then no item is selected, otherwise some item is selected and the index number of the item is in pNmlv->iItem
Thankuoi
|
|
|
|
|
Hey guys, im trying to figure out how I would override a mouse even in Outlook with an add-in i've made. More specifically, I want have my own dialog pop up when i double click an appointment spot in the calendar. Any help would be nice. Thanks
|
|
|
|
|
I apologize for asking this question over and over, but I'm still having trouble with the variables in my application. The problem I am having, for example, is when a CString variable is populated within a particular function, all of the CString variables in that function are populated with the same data and, inexplicably, share the same memory address. Therefore, when the data in one of the variables is changed, all of the others change along with it. I'm not sure what I'm doing wrong. some people have mentioned that I might be overwriting the stack. I'm not sure how to overwrite the stack and so I'm not sure if I'm doing it or how to fix it. Any help would be greatly appreciated.
|
|
|
|
|
Post some code. It sounds like coding error.
|
|
|
|
|
for(int i = 0; i < TempPlaybookFileComboBox.GetCount(); i++)
{
fstream PlaybookFileStream;
CString StrippedFileName;
CString PlaybookFile;
char *pdest;
int result;
int ch = '.';
int slash = '\\';
TempPlaybookFileComboBox.GetLBText(i, PlaybookFileName);
StrippedFileName = PlaybookFileName.Left(PlaybookFileName.GetLength() - 4);
// populate the treectrl
HTREEITEM hti = m_wndPlaybookTree.InsertItem(StrippedFileName);
PlaybookFileStream.open(PlaybookFileLocation + "\\" + PlaybookFileName, ios::binary | ios::in);
while(!PlaybookFileStream.eof())
{
CString PlaybookFilePath;
int PathLength;
PlaybookFilePath = "";
PlaybookFileStream.getline(PlaybookFile.GetBuffer(0), 128, '\n');
PlaybookFilePath = PlaybookFile;
PathLength = PlaybookFile.GetLength();
// strip out the filename from the path-filename combination
pdest = strrchr(PlaybookFile.GetBuffer(0), slash) + 1;
result = pdest - PlaybookFile.GetBuffer(0) + 1;
if (result > 0)
sprintf(PlaybookFile.GetBuffer(0), pdest);
// strip off the extension
pdest = strchr( PlaybookFile.GetBuffer(0), ch );
result = pdest - PlaybookFile.GetBuffer(0) + 1;
// null terminate the string and add to the tree
PlaybookFile.GetBuffer(0)[result - 1] = '\0';
m_wndPlaybookTree.InsertItem(PlaybookFile.GetBuffer(0), hti);
// Allocate memory for new offensive position
ptrPlaybookFileItem = new PlaybookFileRec;
if (ptrPlaybookFileItem == (PlaybookFilePtr)NULL)
{
AfxMessageBox("Unable to allocate memory for Playbook File information", MB_OK);
AfxAbort();
}
ptrPlaybookFileItem->PlaybookFileName = PlaybookFile;
ptrPlaybookFileItem->PlaybookFilePath = PlaybookFilePath;
// Add the Offensive Postion information to the vector
m_PlaybookFiles.push_back(ptrPlaybookFileItem);
}
PlaybookFileStream.close();
}
There's a little snippet of code. The PlaybookFile and PlaybookFilePath variables are mapped to the same memory address.
|
|
|
|
|
This doesn't look right to me.
PlaybookFileStream.getline(PlaybookFile.GetBuffer(0), 128, '\n');
the argument in GetBuffer causes CString to allocate at least that many characters to the buffer. If your CString object starts out with an empty string and you do a GetBuffer(0) you still have no memory allocated. Try this instead.
PlaybookFileStream.getline(PlaybookFile.GetBuffer(0128), 128, '\n');
You must allso call ReleaseBuffer after modifying the string.
|
|
|
|
|
I think Bill Wilson nailed it for you: misunderstanding how CString works, and then abusing it like that usually leads to problems. And whoever you saw using GetBuffer( 0 ) like that should be slapped!
If you assign one CString to another, they will share the same memory. When you instantiate a CString object, it automatically initializes itself to an empty string (which is why you should not initialize them with "" : it just wastes time). Internally, CString s (this is different in VS.NET, BTW) keep an object around referred to by afxEmptyString , which is used to indicate an empty string. Since you have two CString s containing empty strings (thus both pointing to afxEmptyString ), you can see that problems will occur is you then use CString::GetBuffer( 0 ) to get a buffer: you will "step on" (and likely over) the internal afxEmptyString object, and thus screwed every other empty CString out there!
IMHO, I think that you would benefit from not misusing CString objects in the ways your code shows, and use normal char/TCHAR buffers. For example, StrippedFileName and PlaybookFile could likely be plain buffers of MAX_PATH + 1 length, or even 32KB each, which your stack will likely have more than enough room for, and is long enough for a network-based path name. You also avoid the unnecessary hit of dynamic memory allocation.
IME, I have found misuse of CString objects to be pretty damn near, if not right at, the heart of MFC applications with performance problems (esp. after running for an extended period of time, and/or with multiple threads).
Peace!
-=- James.
"Some People Know How To Drive, Others Just Know How To Operate A Car."
(Try Check Favorites Sometime!)
|
|
|
|
|
VS6's class wizard would often add stuff like:
public:
protected:
it used this for the message map, etc.. and i have just deleted em.. what i'm wondering about is this at the begining of my .h files:
#if !defined(AFX_SCTAX_H__9275F024_08D4_11D6_B612_00A0CC5C3AED__INCLUDED_)
#define AFX_SCTAX_H__9275F024_08D4_11D6_B612_00A0CC5C3AED__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif can i get rid of this stuff? and just replace it with what VS .net seems to put at the begining of .h files:
#pragma once
just looks like crap and i'd like to get rid of it once i get a change to run through my code and clean it up..
thanks!
-dz
|
|
|
|
|
If you're asking can you get rid of #if _MSC_VER > 1000, then yes.
The AFX_ define is used to make unique include files. If yours are unique AND you don't share them with anyplace they might not be unique (like CodeProject), then yes.
If you're sure you always have stdafx.h in you include path, then yes.
|
|
|
|
|
I say no.
The
#if !defined(AFX_SCTAX_H__9275F024_08D4_11D6_B612_00A0CC5C3AED__INCLUDED_)
#define AFX_SCTAX_H__9275F024_08D4_11D6_B612_00A0CC5C3AED__INCLUDED_ code is good practice for header files. If you don't like the way it looks you can clean it up a bit
if !defined (_SCTAX_H__INCLUDED_)
#define _SCTAX_H__INCLUDED_ if that makes you happy.
All the //{{AFX...//}}AFX... comments are markers used by the class wizard to added code to your project.
If MFC is going to put this stuff in all the applications you create, why bother tring to delete it all out? I would spend the time writting code instead of deleting comments...
Jonathan Craig
www.mcw-tech.com
|
|
|
|
|
dazinith wrote:
it used this for the message map, etc.. and i have just deleted em..
So you'll be unable to use ClassWizard for adding virtual functions. You'll have to type the member function declaration in header file and function body in .cpp.
And if you get rid of //{{AFX_MSG section, you'll need to add manually three pieces for each message handler - one in .h and two in .cpp files.
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|