Dos filename lookup how to get File Name without Path

Hi,

I am using Dosfilename lookup to return a file. However this is returning the path and filename.

Is there another command to just select and return the filename or do I need to strip out the path of the returned value ?

C10

Thanks

1 Like

Easy to separate path & filename after lookup. See help for fnsplit.

1 Like

The Name is after the last Backslash

  BS  USHORT

    BS=INSTRING('\',PathPlusName,-1,SIZE(PathPlusName))   !-1 Reverse step, must start at the end i.e. size
    NameOnly=SUB(PathPlusName,BS+1,999)
4 Likes

Much easier to use PathSplit that’s found in CWUTIL

                PROGRAM

                MAP
                    include('CWUTIL.INC'),once
                END

theFullPathAndFileName cstring(261)
theFileName cstring(81)

CODE
    
    if filedialog('Select a File',theFullPathAndFileName,'All Files|*.*')
        PathSplit(theFullPathAndFileName,,,theFileName)
        message('FileName ' & theFileName)
    end

It’s not documented anywhere but PathSplit returns an unsigned that shows you what parts of a full file path where present using these equates…

extension equate(2)
file equate(4)
wildcards equate(5)
folder equate(8)
drive equate(16)

3 Likes

Looking in CwUtil.INC PathSplit() is simply renamed from the RTL C Library _fnsplit. You would need to use all CSTRING’s to call it. I’m surprised SV did not create a wrapper function that took Clarion STRING’s.

  MODULE('Core')
    PathSplit(CONST *CSTRING path, <*CSTRING drive>, <*CSTRING dir>, <*CSTRING file>, <*CSTRING ext>), SIGNED, PROC, RAW, NAME('_fnsplit')
    PathMerge(*CSTRING path, <*CSTRING drive>, <*CSTRING dir>, <*CSTRING file>, <*CSTRING ext>), SIGNED, PROC, RAW, NAME('_fnmerge')
  END

You could just declare these C functions in your program, but use different names. I would create a wrapper that took STRINGs … well I would use my posted 2 lines of code and be done.


Edit 11/11/2022:
In the Legacy2ABC project I ran into code calling Split. It had declared Name CSTRING(9) for 8.3 names. That failed with a LFN to return .EXT. Since its RAW it does not know the sizes of the CSTRING’s so overran the 9 bytes and wrote into the Extension.

FNInfoType          GROUP,TYPE
Path                  CSTRING(File:MaxFilePath)
Drive                 CSTRING(3)
Directory             CSTRING(File:MaxFilePath)
Name                  CSTRING(FILE:MaxFileName)
Extension             CSTRING(32)
                    END

FileExtension    PROCEDURE(STRING FullName)
FN    LIKE(FNInfoType),AUTO
    CODE
        FN.Path = CLIP(FullName)
        FNSplit(FN.Path,FN.Drive,FN.Directory,FN.Name,FN.Extension)
        RETURN UPPER(SUB(FN.Extension,2,LEN(FN.Extension)-1))
1 Like

Here is a class I wrote that wraps FnSplit, allowing you to use STRING vs. CSTRING

CwUnit/ctFileHelper.clw at master · MarkGoldberg/CwUnit (github.com)

2 Likes

StringTheory also has a FileNameOnly method, as well as ExtensionOnly and PathOnly.

2 Likes

Using StringTheory;
filename = str.FileNameOnly(PathPlusName)
https://www.capesoft.com/docs/StringTheory3/StringTheory.htm#FileNameOnly
(there’s an option to have it with, or without, the extension.)

I try not to do too much 3rd party promotion here, but honestly if you are writing code, and you’re not using StringTheory then you are just wasting time each and every day.

Cheers
Bruce

2 Likes

I can’t recommend StringTheory (Capesoft) enough. It does all this stuff and so much more!

Mark

1 Like

longpath() & ‘fileA.tps’ works well

Welcome May_Woo. That would indeed work if you were constructing the name. But in this case Sim has the full name and wants to split out just the filename part (ie removing the path part.) So the opposite of your code.

Incidentally it’s not a great idea to use LongPath() in your code to specify file locations, because this is relative to the “current directory”. Since that can be changed (like on the windows shortcut) this can lead to strange bugs. The current directory may also change when using FILEDIALOG, so you get the effect where “data goes missing” after a file lookup is done.

Lastly, LongPath defaults to the Exe folder, and that’s a really bad place to put your data these days. So, all in all, the use of LongPath is a signal that there is something “not quite right” in the way you are doing things.

cheers
Bruce

Bruce thanks for this. I was actually using longpath to get the directory / file and I was actually getting some strange issues when trying to set the default path.

I personally use StringTheory but this is an elegant, non 3rd party, solution.