|
When you say
<br />
char anArray[200]<br />
you are saying "Grab me 200 characters worth of local space and call it "anArray". You could them go on to put "Hello World" into it if you wanted, but only by copying it in character by character, for example with:
<br />
strcpy(anArray, "Hello World!");<br />
However because the space for anArray is local it's discarded as soon as your function exits. A pointer returned to it will point to garbage, because that pointer looses it's validity when the routine exits.
The string constant "Hello World" is a different kind of beasty. The string is stored by the compiler in static storage. It's address remains valid for the life of the program.
When you say, for example,
<br />
const char *p = "Hello World";<br />
You are allocating a pointer. A memory location containing the address of that static string. Not a new block of memory containing the string itself (which is why it's ok to do a simple assignment in such a case rather than a more complex copy).
Does that make things clearer?
|
|
|
|
|
I need the directory in which the executable is in. I can't seem to find a function that just gets the path for the directory.
If the file path is... c:\program files\cool program\program.exe
I need c:\program files\cool program\
I was hoping to do this by a single function call rather than a hideuos solution by getting the whole path and deleting characters from the end until reaching a \
|
|
|
|
|
Why not call GetCurrentDirectory on startup, and store it ?
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
Because GetCurrentDirectory doesn't necessarily return the directory the exe is in. (i think)
I used the debugger and that function, and it showed c:\my documents, while the exe was in c:\my documents\C++ work\Application\Debug\
|
|
|
|
|
How odd - this is how we do it, and have done for as long as I have been here, and it's always worked fine. Are you running it apart from VC, or from within VC ?
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
I was running it from within VC, which is probably the problem then.
|
|
|
|
|
GetModuleFileName or GetModuleFileNameEx should work, or you can parse argv[0].
Isn't this in the FAQ yet?
|
|
|
|
|
As I previously mentioned I wanted to get the directory the file is in, not the file name and its full path.
|
|
|
|
|
I think its a simple parse. Once you have the full path just strrchr for the last '\\', then the next to last, and what remains, however improbable, should be your directory.
later
oops - I think just one strrchr would do it - just read your msg again...
|
|
|
|
|
Or better yet, use stl strings.
string dirAndName = "c:\\Test\\SubDir\\File.Ext";
string directoryOnly = dirAndName.substr( 0, dirAndName.findLastOf('\\') );
Of course, this does no error checking, so if you think there might be no '\' character at all then you'd need to rework this slightly.
|
|
|
|
|
how about using _splitpath
cheers
kannan
|
|
|
|
|
"GetCurrentDirectory" will return you the directory that the current process is running in (fairly obvious from the name, really!!). If you create a desktop shortcut this is the "Start In" entry (at least, that's what it's called under 2000 - I can't remember if NT/95/etc use the exact same terminology).
"GetModuleFileName" will return you the path of the file that the specified module (such as a DLL) was loaded into memeory from. If you pass NULL as the first parameter you get the path of the current process module. You may need to process the returned value from "GetModuleFileName" to extract exactly what you want (path only, filename only, etc) - it's been a while since I did anything like this, so I'm not sure!
|
|
|
|
|
But if you call to GetCurrentDirectory when the application start you can get the directory. But dependes the application. If the App is runing like NT service the currentdirectory will be System32
Cheers!!!
Carlos Antollini.
|
|
|
|
|
Here's a crap-load of filename code I use a lot. The function you're interested in is at the bottom, and it relies on one or two of the other functions. You didn't specify, but I assume you're using VC++ and MFC.
Here's the header file (FILENAME.H) :
#ifndef __FILENAME_H
#define __FILENAME_H
CString justFileName(LPCSTR);
CString justName(LPCSTR);
CString justExtention(LPCSTR);
CString justPath(LPCSTR);
CString justDrive(LPCSTR);
CString forceExtention(CString fn, CString newext);
CString forceFileName(CString fn, CString newname);
CString forcePath(CString fn, CString newpath);
BOOL FileExists(CString fn);
int DeleteFile(CString fname);
int RenameFile(CString oldname, CString newname);
void AddBackSlash(CString& path);
CString RemoveBackSlash(CString path);
CString GetProgramPath(BOOL bAndExeName=FALSE);
#endif
And here's the CPP file (FILENAME.CPP) :
#include "stdafx.h"
#include "filename.h"
#include <io.h>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CString justFileName(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = file;
st += ext;
return st;
}
CString justName(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = file;
return st;
}
CString justPath(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f, drive, dir, file, ext);
st = drive;
st += dir;
return st;
}
CString justExtention(LPCSTR f)
{
char drive[_MAX_DRIVE],
dir[_MAX_DIR],
file[_MAX_FNAME],
ext[_MAX_EXT];
CString st;
_splitpath((char *)f,drive,dir,file,ext);
st = ext;
return st;
}
CString forceExtention(CString fn, CString newext)
{
CString st = justPath(fn);
st += justName(fn);
st += newext;
return st;
}
CString forceFileName(CString fn, CString newname)
{
CString st = justPath(fn);
st += newname;
st += justExtention(fn);
return st;
}
CString forcePath(CString fn, CString newpath)
{
CString st = newpath;
AddBackSlash(st);
st += justFileName(fn);
return st;
}
BOOL FileExists(CString fn)
{
BOOL exists = FALSE;
if (!fn.IsEmpty())
{
int status = _access(fn,0);
if (status == 0)
exists = TRUE;
}
return exists;
}
int RenameFile(CString oldname, CString newname)
{
int status = 0;
BOOL oldexists = FileExists(oldname);
BOOL newexists = FileExists(newname);
if (oldexists && !newexists)
CFile::Rename(oldname, newname);
else
status = -1;
return status;
}
int DeleteFile(CString fname)
{
int status = 0;
if (FileExists(fname))
CFile::Remove(fname);
else
status = -1;
return status;
}
void AddBackSlash(CString& path)
{
int length = path.GetLength();
if (length > 1)
{
if (path.GetAt(length - 1) != '\\')
{
path += "\\";
}
}
else if (1 == length)
{
CString temp = path;
temp.MakeUpper();
TCHAR ch = temp.GetAt(0);
if (ch >= 'A' && ch <= 'Z')
{
path += ":\\";
}
else if (ch != '\\')
{
path += "\\";
}
}
else
{
path += "\\";
}
}
CString RemoveBackSlash(CString path)
{
if (path.Find('\\') == 0)
return path;
int len = path.GetLength();
path = path.Left(len - 1);
return path;
}
CString GetProgramPath(BOOL bAndExeName)
{
TCHAR szFullPath[MAX_PATH];
::GetModuleFileName(NULL, szFullPath, MAX_PATH);
CString path = szFullPath;
if (!bAndExeName)
{
path = justPath(path);
AddBackSlash(path);
}
return path;
}
|
|
|
|
|
Thanks for all the input. Just to let you all know, GetCurrentDirectory() doesn't cut it, your current working directory seems to have nothing to do with your exe path. Anyway, the easiest way I found is shown below.
CString File;
GetModuleFileName(NULL, File.GetBuffer(MAX_PATH), MAX_PATH);
File.ReleaseBuffer(File.ReverseFind('\\') + 1);
If the exe path was say... "c:\my documents\code\program\app.exe", the File CString is "c:\my documents\code\program\"
RE: John Simmons / outlaw programmer (or anyone else who knows how to...)
How do you get your code to show up like that on a message? (With the yellow background, and formatting in-tact)
THANKS!
John
|
|
|
|
|
Is it possible to simulate a carriage return in VC++? Basically I’m trying to have my application "push the enter key" on a specified event.
Thanks in advance for your help!
Rob
|
|
|
|
|
Do you want to add a carriage return to a text box, push OK, or what ?
Christian
#include "std_disclaimer.h"
People who love sausage and respect the law should never watch either one being made.
The things that come to those who wait are usually the things left by those who got there first.
|
|
|
|
|
Try
this->PostMessage(WM_OK);
Or if you want to SEE the click, your going to have get Spy++ out
and capture all the WM_COMMAND message & parameters and figure out
which one(s) to Post/Send to the window.
Julien.
|
|
|
|
|
To simulate a carriage return all you need to do is called CWnd::GetWindowText() giving the CString obj you want to fill. Next you append the "\n" (Newline Character in C/C++) to the end of the CString obj using the "+=" operator. Lastly, you use CWnd::SetWindowText().
This is for MFC only.
Check MSDN on how to use CWnd::GetWindowText(), the "+=" operator, and CWnd::SetWindowText().
|
|
|
|
|
Can anyone tell me how to convert a:
BYTE *btArray ==> CStringArray
I would really appreciate it.
Thanks in advance,
Dan
|
|
|
|
|
Hmm. I believe you need to convert it to a CString, not to a CStringArray.
CString is a string class (like the STL 'string'), while CStringArray is an array of strings (like an STL 'vector<string>').
I guess btArray is a pointer to an array of characters (a 'C' string).
To convert it to a CString, this should be enough:
CString s = btArray;
CStringArray can hold many CStrings, and it resizes dynamically.
You can, for example: CStringArray sa; sa.Add(s); sa.Add("Hello");
After this, sa[0] is a CString and you can do:
sa[0] = "SomeString";
printf("My String is: %s\n", (LPCTSTR)sa[0]);
Hope this helps,
Pavlos
|
|
|
|
|
Doesn't work...I get:
const CString& CString::operator=(LPCTSTR lpsz)
{
ASSERT(lpsz == NULL || AfxIsValidString(lpsz)); <=========== Error is here!
AssignCopy(SafeStrlen(lpsz), lpsz);
return *this;
}
HERE is an example of the code:
//BYTE btArr[3] = {67,245,67}; <========= I can see this!
BYTE *btArr = lpVal[3].Value.bin.lpb;
CString s = _T("");
s = btArr; <=========================== Error!
s = lpVal[3].Value.bin.lpb[0]; <======== Error!
MessageBox(0,s,"",0);
Thanks in advance,
Dan
|
|
|
|
|
>> AfxIsValidString(lpsz)
This function checks if the address you have passed in points to memory that your program has 'read' access to. This routine looks for a terminating NULL char, since all valid 'C' and windows strings must have terminating NULL. All characters between the starting address and the terminating NULL must be in valid 'read' access memory.
Looking at your samp,e code, you appear to be passing the address of an array that has no terminating NULL, so this is why the attempt to load the CString from this memory is failing.
The bigger question is why you want to load and array 'byte' data, which does not appear to be a valid string value, into a CString ??
|
|
|
|
|
I have written a program that processes mails from Outlook into a Database. I noticed that the Messages are being cut off after 255 characters. When reading the message text I am using:
"CString csBody = lpVal[3].Value.lpszA;" which gives be only 255. another value is:
"lpVal[3].Value.bin.lpb;" which returns a LPBYTE...see below (from MSDN). I have also looked at "lpVal[3].Value.bin.cb;" which returns "8792808"?? I am basically really confused!
typedef struct _SBinary
{
ULONG cb;
LPBYTE lpb;
} SBinary, FAR *LPSBinary;
Members
cb
Count of bytes in the lpb member.
lpb
Pointer to the PT_BINARY property value.
Thanks in advance,
Dan
|
|
|
|
|
Ok. You will need to rethink this, or approach things fromn another angle. The "lpVal[3].Value.bin.lpb" variable is NOT a suitable pointer to initialize a CString with. By definition, a CString is useful for holding NULL terminated plain text. It IS possible to make a CString hold binary info, but that's a topic for another day (and a much longer discussion!)
What you need to do first is find out why you only get 255 chars from the "lpVal[3].Value.lpszA" pointer. I don't knowe the Outlook format at all, but this sounds like the data you want - yet it's being truncated. Chase that down first.
If you find that you really do need to process the binary data in order to get the full body of text (sounds strange, but might be true), then I'd suggest the STL vector (or perhaps stringstream) as a better container for working with the binary data you want to process.
|
|
|
|
|