using dir$ to fill an array
-
- Posts: 274
- Joined: Oct 13, 2005 2:05
- Contact:
using dir$ to fill an array
i want to fill an array with all the folders in c:\ and fill another array with all the files in c:\. how?
i think this question has been answered b4, but i still dont get it lol.
i think this question has been answered b4, but i still dont get it lol.
one way ...
This is a bit odd to me because DIR$() returns results which are opposite to what I expected from using PowerBasic and VB, ie, I expected DIR$("C:\*.*") to not return directories, and DIR$("C:\*.*",16) to return directories plus normal files. The Wiki isn't particularly clear; The filespec can be "*" for all files/directorys, "*.*" for all files, or you can change the "*" to the file/directory name or filetype you want to search for.
And now I'm confused ....
The above code works on my PC and on most directories where there is a mix of directories and files ( ie "C:\TMP\*.*" ), but not on all ! In a couple of directories, including DIR$("C:\WINDOWS\*.*",16), it is actually returning non-directory files.
A FreeBasic bug maybe ?
Code: Select all
Option Explicit
Dim directoryArray$(1000)
Dim fileArray$(1000)
Dim directoryArrayTop&
Dim fileArrayTop&
Dim filename$
Dim i&
filename$ = DIR$("C:\*.*",16)
WHILE filename$ <> ""
directoryArrayTop& = directoryArrayTop&+1
directoryArray$(directoryArrayTop&) = filename$
filename$ = DIR$
WEND
filename$ = DIR$("C:\*.*")
WHILE filename$ <> ""
directoryArray$(0) = filename$
i& = directoryArrayTop&
WHILE directoryArray$(i&) <> filename$
i& = i&-1
WEND
IF i& = 0 THEN
fileArrayTop& = fileArrayTop&+1
fileArray$(fileArrayTop&) = filename$
END IF
filename$ = DIR$
WEND
FOR i& = 1 TO directoryArrayTop&
PRINT "Directory = ",directoryArray$(i&)
NEXT
FOR i& = 1 TO fileArrayTop&
PRINT "File = ",fileArray$(i&)
NEXT
And now I'm confused ....
The above code works on my PC and on most directories where there is a mix of directories and files ( ie "C:\TMP\*.*" ), but not on all ! In a couple of directories, including DIR$("C:\WINDOWS\*.*",16), it is actually returning non-directory files.
A FreeBasic bug maybe ?
Most people don't understand the gravity of using wildcards in their path specifiers.
"*.*" will match any file or folder that has a peroid (.) in its name.
".*" will match any file or folder with a period at the beginning of its name.
"*." will match any file or folder with a period at the end of its name.
"*" will match any file or folder, regardless of its name.
The asterisk (*) as a wildcard means "zero or more characters of any type".
"*.*" will match any file or folder that has a peroid (.) in its name.
".*" will match any file or folder with a period at the beginning of its name.
"*." will match any file or folder with a period at the end of its name.
"*" will match any file or folder, regardless of its name.
The asterisk (*) as a wildcard means "zero or more characters of any type".
-
- Posts: 274
- Joined: Oct 13, 2005 2:05
- Contact:
sh*t so in UnrealTournament it finds CTF(Capture The Flag)(or any map type) by doing this "CTF-*"tunginobi wrote:Most people don't understand the gravity of using wildcards in their path specifiers.
"*.*" will match any file or folder that has a peroid (.) in its name.
".*" will match any file or folder with a period at the beginning of its name.
"*." will match any file or folder with a period at the end of its name.
"*" will match any file or folder, regardless of its name.
The asterisk (*) as a wildcard means "zero or more characters of any type".
wow!!! i didnt know that thx!!
So why does DIR$("C:\*.*",16) return only directory names such as "WINDOWS" and not the names of files such as "AUTOEXEC.BAT" which exist there, yet a DIR$("C:\WINDOWS\*.*",16) returns directory names and also some, but not all, the names of files, like "Setup1.EXE" ?tunginobi wrote:"*.*" will match any file or folder that has a peroid (.) in its name.
".*" will match any file or folder with a period at the beginning of its name.
"*." will match any file or folder with a period at the end of its name.
"*" will match any file or folder, regardless of its name."
Something's not right there.
Also, if "*.*" matches files and folders which have periods, what of "C:\WINDOWS" ? Does that have a period in it ? If it does, then implicitly so does every directory name and filename. If it doesn't, then why is it returned with "*.*" ?
So what's broken ? The description of what the wildcards do, or the implementation of DIR$ which doesn't match the description ? Maybe both are wrong ?
What is the source of that interpretation as claimed by tunginobi ? That's not what it says on the FB Wiki, which is the same as in the 10-dec-2005 .CHM file ...
http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgDir
Description:
Returns files/directorys in the current directory/folder. Results can be filtered with a filespec and with a matching file attribute. The filespec can be "*" for all files/directorys, "*.*" for all files, or you can change the "*" to the file/directory name or filetype you want to search for.
But is that because it's meant to do that and tunginobi's statements are wrong ( or perhaps irrelevant if refering to Linux while we're all talking about Windows ), or does it do that because DIR$ isn't working as it should ?yetifoot wrote:on windows *.* will return files named like 'COPYING' (which has no dot)
We need a developer who can definitively say what DIR$ is meant to do, then from that we can assess what's right or wrong, and whether DIR$ does as it should.
I'm stating the way that wildcards do operate. They may or may not operate that way in the DIR$ function.
It's largely because the "*.*" pattern is so ubiquitous in the realm of file management. People who didn't really understand the operation of computers would see something like "copy *.* a:" and think, "I'm copying all the files to my floppy disk!"
What they didn't realise is that "*.*" isn't necessarily equal to "all files". The stigma that it did mean that has propagated through computing, and has been incorrectly incorporated into a number of programs over the years.
Such mistakes would be unacceptable on a UNIX-based system. Try "ls *.*" on a UNIX-based shell, and indeed, all the entries must contain a period somewhere in their name. Type "dir *.*" and you indeed get a similar result.
Here's a quote from the relevant Wikipedia page:
It's largely because the "*.*" pattern is so ubiquitous in the realm of file management. People who didn't really understand the operation of computers would see something like "copy *.* a:" and think, "I'm copying all the files to my floppy disk!"
What they didn't realise is that "*.*" isn't necessarily equal to "all files". The stigma that it did mean that has propagated through computing, and has been incorrectly incorporated into a number of programs over the years.
Such mistakes would be unacceptable on a UNIX-based system. Try "ls *.*" on a UNIX-based shell, and indeed, all the entries must contain a period somewhere in their name. Type "dir *.*" and you indeed get a similar result.
Here's a quote from the relevant Wikipedia page:
Computing
In computer (software) technology, a wildcard character can be used to substitute for any other character or characters in a string.
The asterisk (*) usually substitutes as a wildcard character for any zero or more characters, and the question mark (?) usually substitutes as a wildcard character for any one character, as in the CP/M, DOS, Microsoft Windows and POSIX (Unix) shells. (In Unix this is referred to as glob expansion.) In SQL, the wildcard characters are percent (%) for zero or more characters, and underscore (_) for one character. In many regular expression implementations, the period (.) is the wildcard character for a single character.
Dir("*.*", 16) is returning directories plus files that have no attribute set at all. This might be a bug, but, it of course depends on the expectation of Dir().
VBDOS has a Dir(spec) command that doesn't have an attrib parameter. Visual Basic has Dir(spec, attrib) that doesn't exactly do it right. You still have to use GetAttr() to really know what it is. (And if it matches the type of file/dir you are looking for)
The problem is that files that have no attributes at all (effectively a zero value) cause a problem. How do you include or exclude a zero value based on a bit mask consistently?
Dir() as it is without GetAttr() is not useable as is for some tasks and findfirstfile(), findnextfile() could be used instead. If it were up to me, I would fix Dir() by introducing an artificial attrib to indicate "is a file"
linux file systems don't have attribs the same was as dos, so most of them are simulated for use with the dir() function. I don't think there's any plans to support GetAttr().
VBDOS has a Dir(spec) command that doesn't have an attrib parameter. Visual Basic has Dir(spec, attrib) that doesn't exactly do it right. You still have to use GetAttr() to really know what it is. (And if it matches the type of file/dir you are looking for)
The problem is that files that have no attributes at all (effectively a zero value) cause a problem. How do you include or exclude a zero value based on a bit mask consistently?
Dir() as it is without GetAttr() is not useable as is for some tasks and findfirstfile(), findnextfile() could be used instead. If it were up to me, I would fix Dir() by introducing an artificial attrib to indicate "is a file"
linux file systems don't have attribs the same was as dos, so most of them are simulated for use with the dir() function. I don't think there's any plans to support GetAttr().
Okay, but that is in many ways irrelevant to the issue of what DIR$ does and what DIR$ is meant to do, and doesn't do much but cloud the issue at hand.tunginobi wrote:I'm stating the way that wildcards do operate. They may or may not operate that way in the DIR$ function.
It is also not correct to say that is the "way that wildcards do operate" as if that is a universal absolute. It's the way they "usually" work ( as the Wikipedia entry acknowledges ), but by no means certain that wildcards will work that way for anything other than specific implementations.
I could be wrong as I don't have a linux box to test this on but by looking at the rtl source, it would seem that: *.* and * both return "all files and folders" (igrnoring the attrib param atm) on dos/win and linux. the linux implementation of dir() checks for "*.*" and uses "*" instead. This was likely added for compatibility between dos/win and linux, and usage of *.* in existing qbasic progs.
I think the Dir() function regarding *.* is just documented incorrectly in the wiki.
I think the Dir() function regarding *.* is just documented incorrectly in the wiki.
Thanks for that info. The primary issue for me is whether DIR$("*.*") should return (A) files only, or (B) files plus directories, and DIR$("*.*",16) should return (A) just directories, or (B) files plus directories.
DIR$("*.*",16) is returning all directories (as best I can tell ), but is also returning some but not all files. Either way it is meant to work there seems to be a bug, in returning too much or too little.
DIR$("*.*",16) is returning all directories (as best I can tell ), but is also returning some but not all files. Either way it is meant to work there seems to be a bug, in returning too much or too little.
If there's no GetAttr() equivalent, then I think Dir("*.*", 16) should just return directories. (So right now it's bugged) But even if that's fixed, there are still be cases where Dir("*.*", attrib) won't work right because the bitmask that's specified in attrib could be used in two ways: files matching "Any" attrib or "All" attribs.
Another idea to fix this would be a GetLastAttr() function that returns the attrib of the file/dir just returned in the last Dir() call. Seems like it should be possible based on what's already in the run-time lib's Dir() funtion. This would allow the programmer to check the attrib after the Dir() call instead of relying only on the filtering in Dir().
Another idea to fix this would be a GetLastAttr() function that returns the attrib of the file/dir just returned in the last Dir() call. Seems like it should be possible based on what's already in the run-time lib's Dir() funtion. This would allow the programmer to check the attrib after the Dir() call instead of relying only on the filtering in Dir().
What instead if we use a third optional argument to DIR? This would be a variable passed by reference, that would be filled with the attribs mask of the file returned each time DIR is called.
Ok, the dir(,,attribs) form is not that cool, but at least this way we avoid introducing a new keyword...
Code: Select all
dim as string filename
dim as integer attribs
filename = dir("*.*",,attribs)
while filename <> ""
print "File: " & filename & " (attribs: " & attribs & ")"
filename = dir(,,attribs)
wend
-
- Posts: 1706
- Joined: May 27, 2005 6:34
- Location: Cambodia, Thailand, Lao, Ireland etc.
- Contact: