Hi all,

Using my application I've found a file path anywhere on my machine and store the full path in a CString variable. That is full path, like this,

G:\Work On\CPP\001_002_003.txt

What I want to do is, find the name of the file(without the extension), 001_002_003 according to my example. Then separate as 001 002 and 003, then write them to a file in three columns.

I'm stuck with how to get that three part, 001 002 and 003, from the full file path.

Thanks.

DOS used to have a 'splitpath' function which returned the various components of a full path.

Or you could do
- find the last \ to mark the start of the filename
- find the last . to mark the end of the filename.

Or you could do
- find the last \ to mark the start of the filename
- find the last . to mark the end of the filename.

Can you tell me about this more. Any worked example really appreciate.

> Can you tell me about this more. Any worked example really appreciate.
What did your last slave die of?

Are you totally incapable of digging around in the manual pages to see what the CString API is capable of, or do you have to be told every single detail in advance before you try to use it?

Ok, at the end I have done it myself using MSDN. Used CFindFile class and FindNextFile() to do that. Like this.

CFileFind fileName;

static const TCHAR UseFile[] = _T("F:\\Resources\\Files\\ReadFile.txt");

BOOL ress = fileName.FindFile(UseFile);
fileName.FindNextFile();
if(ress)
{
		AfxMessageBox((LPCSTR)fileName.GetFileTitle(), MB_OK);
}

I want to use a CString here, because file path is on CString format, which I have already found. Can you give me a clue how to use it here in this code.

That mean I have to cast CString to a char buffer, is that right? Is it possible?

OMG why in the world are you doing that just to extract the name part of the string! If the CString already contains the full path + filename just use its Find() method to locate the last '\' and you have the name starting with the next character.

>>That mean I have to cast CString to a char buffer, is that right? Is it possible?
Depends -- is your program compiled for UNICODE or not. If it is, then CString can not be simply typecase, it must be converted from wchar_t* to char* with one of the conversion functions.

I have tried one thing. Use ReverseFind() method of CString class to find the last '\' sign. Then I used the Right() to get the required file name. I can use Right() easily because file name length is always fixed.

CString ss = "F:\\Files\\ReadFile.txt";
	CString aa;

	if(ss.ReverseFind('\\')== 8)
	{
	AfxMessageBox(ss.Right(12), MB_OK);
	aa = ss.Right(12);
	}

	if(aa.ReverseFind('.')==8)
	{
		AfxMessageBox(aa.Left(8), MB_OK);
	}

Actually this code gives the file name, ReadFile.

But there is a real issue, on the first 'if' condition. First part of the path, that is "F:\\Files" is not fixed. So in the first 'if' condition number 8 can be change depend on the file selection on my PC. How can avoid that.

> if(ss.ReverseFind('\\')== 8) What does this return if there is no \\ ?

In other words, do something like

int pathStart = ss.ReverseFind('\\');
if ( pathStart >= 0 ) {
  // using the position and length of the string, you can now do say
  aa = ss.Right(12);
  // but replace the 12 with some kind of calculation based on the dynamic
  // results you've calculated so far
}

Also, don't assume that the extension is
a) always present
b) always 3 characters.

> if(ss.ReverseFind('\\')== 8) What does this return if there is no \\ ?

That what I'm really worried. That number is not fix always. It means, \\ can be missing in such instances.

I've try something like this also,

CString aa = fileName.Right(fileName.GetLength() - (fileName.ReverseFind('\\') + 1));

Actually it gives the file path. Then use ReverseFind() again and find the '.', use a Left() to get the name only.

As you say, if the extension is missing this wont work.

Like I said, read the manual and find out what is returned when there is nothing to find, and use the appropriate if / else constructs to deal with it.

std::wstring PathToFileName(std::wstring strPath)
{
    size_t found1 = strPath.rfind(L'\\');
    size_t found2 = strPath.rfind(L'/');

    size_t found = (found1!=std::wstring::npos) ? ( (found2!=std::wstring::npos) ? max(found1,found2) : found1 ) : found2;

    std::wstring result = strPath.substr(found+1, strPath.length() - found-5);

    return result;
}

Edited 3 Years Ago by Dani: Formatting fixed

int main()
{
char pscL_Dir[]="/home/srfuser/kush/folder/kushvendra.txt";
char pscL_FileName[50];
char pscL_FilePath[100];
char *pscL;
pscL=strrchr(pscL_Dir,'/');
if(pscL==NULL)
printf("\n ERROR :INvalid DIr");
else
{
strncpy(pscL_FilePath,pscL_Dir,(pscL-pscL_Dir));
strcpy(pscL_FileName,pscL+1);
printf("LENTH [%d}\n pscL_FilePath[%s]\n pscL_FileName[%s]",(pscL-pscL_Dir),pscL_FilePath,pscL_FileName);
}
return 0;
}

output:

LENTH [25}
pscL_FilePath[/home/srfuser/kush/folder]
pscL_FileName[kushvendra.txt

Edited 3 Years Ago by Nick Evan: Fixed formatting

Really? How's bout this?(Yes, from the old school...)

char temp2[1024];
char *GetFileNameOnly(char *filename)
{
    char temp1[1024];
    char *F;
    int i = 0;
    F=strrchr(filename,'/');
    strcpy(temp1,F+1);
    while(F[i] != '.')
    {
        temp2[i] = temp1[i];
        i++;
    }
    temp2[i-1] = '\0';  
    return temp2;
}
This article has been dead for over six months. Start a new discussion instead.