Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chriss Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Getting a list of file names 1

Status
Not open for further replies.

AdaHacker

Programmer
Sep 6, 2001
392
US
This is probably really easy, but being unfamiliar with FoxPro, I don't even know where to look.

I want to get a list (an array, a delimited string - whatever) of files in a directory that match a certain regular expression. Looping through all the files is what I eventually want to do, e.g. a
for each file matching <reg exp> do whatever
kind of loop.

Sorry if this is insanely easy and a waste of your time. Thanks in advance!
 
If you can live with the standard DOS file &quot;wildcards&quot; * and ?, then take a look at ADIR(). Even if this is not enough then it's a place to start. Note: Due to Array limitations, you can only return ~13,000 files.

Another option is to use sys(2000) in a loop to get the first and next file that matches a similar wildcard file pattern. This has the advantage of being able to just process the files one at a time. It also opens a small &quot;hole&quot; a bit larger if the files in the directory can be changing during the processing.

If you have specific questions on either technique, post back.

Rick
 

=ADIR(myArray,&quot;my*.*&quot;)
** remember to put the my*.* within quotes where 'my' is the search of all my* files

To know the total number of files in the above array...
myCount=ALEN(myArray)
? myCount

:)
ramani :-9
(Subramanian.G)
FoxAcc
ramani_g@yahoo.com
LET KNOW IF THIS HELPED. ENOUGH EXPERTS ARE HERE TO HELP YOU OUT! BEST OF LUCK :)
 
Rick,

Thanks for the response, it was really helpful. Fortunately, all I really need are the standard wildcards, and I probably won't be getting more than a dozen files in the list, so ADIR() may be an option.

Just one quick question regarding ADIR. According to the FoxPro 2.6 language reference, ADIR returns an array with 5 coolumns, one each for name, size, date, time, and attributes. Am I correct in assuming that each file matching the expression will have a 5 element &quot;entry&quot;? In other words, if I get 3 matches, will the three file names I need be located at, e.g. samparray(1), samparray(6), and samparray(11)?

If that's not correct, what does it do? Does it return a 2 dimensional array? (Does ForPro even have 2 dimensional arrays?)
 
Yup, it's a 2-D array, although FP allows you to access it as a 1-D array if you want, since all rows (by definition) will have the same number of columns.

samparray[1,1] == samparray[1]
samparray[1,2] == samparray[2]
samparray[2,1] == samparray[6]
samparray[3,1] == samparray[11]

As you may have noticed, samparray[1,1] is also the same as samparray(1,1). Historically brackets &quot;[]&quot; have been used for arrays and parenthesis &quot;()&quot; have been used for surrounding function parameter lists - however, either works just fine.

And just to help &quot;confuse&quot; things character strings can be delimited by single quotes, double quotes or brackets.
So 'abc' == &quot;abc&quot; == [abc]
This allows things like:
lcName = &quot;Pat O'Brien&quot;
lcQuote = [He said &quot;It's Mine!&quot;]

Welcome to the wonderfully &quot;rich&quot; world of FoxPro!

Rick
 
Okay, I've got more problems.

I've been playing with the ADIR() and SYS(2000) functions, and I think I understand them.

However, I need to read in a string and process it to a regular expression, which I will then pass to either adir or sys(2000). The problem is, I can't get either function to read the string! I get the string all set up (discovered the Trace and Debug windows today, so I checked that it was correct) and then I call, e.g. =adir(myarray,pattern) or sys(2000,pattern) and it returns a whole list of files that don't match the pattern. For example, I set pattern to &quot;*1299.DBF&quot; and the first file it matches is something called STUFF95.DBF.

To sum up, how can I pass either of these functions a variable containing the pattern I want to search for? What am I missing?
 
Hi
pattern=&quot;'*1299.dbf'&quot;
=adir(myArray,&pattern)
This will give you the result.

When you code....
=ADIR(myArray,&quot;my*.*&quot;)
note that you have to put my*.* within quotes,, i.e. &quot;my*.*&quot;
SO when you want to substitute by macro.. you have to put that as
pattern = &quot;'my*.*'&quot;
=adir(myArray,&pattern)

Hope this helps :)
ramani :-9
(Subramanian.G)
FoxAcc
ramani_g@yahoo.com
LET KNOW IF THIS HELPED. ENOUGH EXPERTS ARE HERE TO HELP YOU OUT! BEST OF LUCK :)
 
Hmmm....
For some reason, this doesn't seem to be working. I tried hard coding it just like you posted, and it still didn't work. The following is copied and pasted right from the program:

pattern=&quot;'*1299.DBF'&quot;
=ADIR(namearr,&pattern)

I have the debug window watching namearr(1,1), and it still comes up as &quot;STUFF95.DBF&quot;. Why is this happening?

Thanks in advance!
 
Also, you cannot use a &quot;*&quot; as the first character, because FoxPro assumes you want everything after the '*'. You can use '?' as a replacement for 1 character, '??' for two, etc.

=ADIR(&quot;*1299.DBF&quot;) &&... returns *.DBF
=ADIR(&quot;12*99.DBF&quot;) &&... returns 12*.DBF
=ADIR(&quot;1299*.DBF&quot;) &&... returns 1299*.dbf

=ADIR(&quot;?1299.DBF&quot;) &&... returns A1299.dbf, B1299.DBF,...
=ADIR(&quot;??1299.DBF&quot;) &&... returns 011299.dbf, 021299.dbf,...
=ADIR(&quot;12??99.DBF&quot;) &&... returns 120199.dbf, 120299.dbf, ...

By the way, ADIR() returns a value corresponding to the number of files it found matching the search criteria. For example:

nFiles = ADIR(aFileAry, &quot;*.DBF&quot;)

If there are 2 .DBFs in the current directory, nFiles will equal 2.

Dave S.
 
Thanks for the suggestion Dave, but that doesn't work either. I tried using &quot;'?*1299.DBF'&quot; and it gave me the same thing. However, when I changed it to &quot;'C*1299.DBF'&quot; it worked correctly. The problem is, with the way the program is set up right now, the only part of the file name I can search on is the end! I'll have several files all starting with a different sequence of characters, so I can't know anything before the * in the above examples.

Is there ANY way to convince FoxPro to search on just the last half of the filename? O am I going to have to change the naming convention (which is doable, but a huge pain)?

One other question for all you FoxPro veterans.
I have an if block beginning with the line:
if (filename != &quot;&quot;) then
I set the variable filename earlier in the program with the following line:
filename=namearr(1,1)
I'm watching it in the debug window, so I know that filename is not the null string. (In most cases, it was &quot;STUFF95.DBF&quot;. Arrgh!) Now, when I get to the if block, it checks the condition and skips right to the end of the block, as though the condition were false. But it's clearly not!
So what's up? Is there some problem with my syntax?

P.S. - Thank you all for all your help! This project would be completely dead in the water without you.

 
Let me reiterate, everything after the '*' gets ignored.
'?*1299.DBF' gets interpreted as '?*.DBF'. Since you are using FoxPro which was originall written for Windows 3x, there is a limitation of 8.3 for file names. You have to use either '?1299.DBF' or '??1299.DBF' in order for Fox to find the 1299 part of the file name.

A gotcha of Fox is that depending on the setting of EXACT, the null string is equal to everything. I have always used the ALLTRIM() function, as in the statement:

IF LEN(ALLTRIM(filename)) > 0
*... do stuff
ELSE
*... empty filename var
ENDIF

Dave S.
 
And to emphasize what Dave is saying, as I pointed out in my first message both ADIR() and SYS(2000) use the DOS wildcard meanings NOT the current Windows interpretation <s>.

That's why SYS(2000) may be your best option - just use it to &quot;pre-process&quot; the .DBF's. So some sample code might be:
Code:
Pattern = &quot;1299.DBF&quot; && make sure all letters uppercase
lcnext_file = SYS(2000, '*.DBF')
DO WHILE ! EMPTY(lcnext_file)
   IF pattern $ UPPER(lcnext_file)
      ... && Process this file
   ENDIF
   lcnext_file = SYS(2000, '*.DBF', 1)	&& get next one
ENDDO

Rick


 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top