From: Jason B. <red...@ya...> - 2004-12-31 21:20:41
|
I'm trying to delve into more complex C programming. I want to know how to use io.h (linked to by dir.h) for functions such as findfirst and so on with the purpose of creating programs that can search for files or perhaps perform like ls/dir. I have found a few examples that work. One is Windows API, but I'm not trying to do this with Windows API. The other uses dirent.h. I've heard that this sort of thing is very compiler/OS specific, so once I have this figured out for GCC, there shouldn't be anymore problems. I am slightly confused on how to declare and deal with the struct involved. Finally, how easily would this directory parsing routine port to another OS or processor. I'd appreciate any advice. Thanks. Jason Benjamin |
From: John G. <jo...@jo...> - 2004-12-31 22:23:31
|
Jason Benjamin wrote: > I've heard that this sort of thing is very compiler/OS specific... Correct. Directory and file handling functions are specific to the operating system. The C/C++ libraries provide the means to open and read/write files, but that is about it. Renaming and moving files, creating directories, etc. requires either OS-specific API calls or making system calls to stuff like "rm" or "mv". I searched Sourceforge and could not find a library that handles this. You may want to write a module that uses conditional compilation to provide a common interface but OS-specific functions on the back-end. That or use Perl if possible. -- John Gaughan http://www.johngaughan.net/ jo...@jo... |
From: Paul G. <pa...@pa...> - 2004-12-31 23:14:34
|
Hi > Jason Benjamin wrote: >> I've heard that this sort of thing is very compiler/OS specific... > > Correct. Directory and file handling functions are specific to the > operating system. The C/C++ libraries provide the means to open and > read/write files, but that is about it. Renaming and moving files, > creating directories, etc. requires either OS-specific API calls or making > system calls to stuff like "rm" or "mv". > > I searched Sourceforge and could not find a library that handles this. You > may want to write a module that uses conditional compilation to provide a > common interface but OS-specific functions on the back-end. That or use > Perl if possible. If you want cross-platform and you're prepared to go to C++ then I believe the boost (www.boost.org) file library will do what you want. Regards Paul Paul Grenyer email: pa...@pa... web: http://www.paulgrenyer.co.uk Elephant: http://www.paulgrenyer.dyndns.org/elephant/ Darrell "Dimebag" Abbott will be sorely missed. |
From: Tor L. <tm...@ik...> - 2005-01-01 02:37:54
|
Paul Grenyer writes: > If you want cross-platform and you're prepared to go to C++ then I believe > the boost (www.boost.org) file library will do what you want. I find it a bit sad that something as new and designed-from-scratch like boost doesn't use the wide-character API on Windows. I understand that they don't want to provide a wide-character API for boost itself, but they should IMHO internally use wide-character APIs and then take/return UTF-8 in the boost API. Hmm, of course, this then would mean that file names returned from boost couldn't be passed to the standard "char" file open functions (which on Windows take system codepage strings), and they would have to provide wrappers for these, too. Oh well, maybe they did consider this and chose to ignore the issue. --tml |
From: Greg C. <chi...@co...> - 2005-01-01 13:42:32
|
On 2004-12-31 10:08 PM, Tor Lillqvist wrote: > > I find it a bit sad that something as new and designed-from-scratch > like boost doesn't use the wide-character API on Windows. I understand > that they don't want to provide a wide-character API for boost itself, > but they should IMHO internally use wide-character APIs and then > take/return UTF-8 in the boost API. > > Hmm, of course, this then would mean that file names returned from > boost couldn't be passed to the standard "char" file open functions > (which on Windows take system codepage strings), and they would have > to provide wrappers for these, too. Oh well, maybe they did consider > this and chose to ignore the issue. It was a deliberate choice to use 'char' names. See http://boost.org/libs/filesystem/doc/faq.htm under the heading "Why aren't wide-character names supported? \ Why not std::wstring or even a templated type?" |
From: Tor L. <tm...@ik...> - 2005-01-01 16:10:57
|
Greg Chicares writes: > It was a deliberate choice to use 'char' names. See > http://boost.org/libs/filesystem/doc/faq.htm > under the heading > "Why aren't wide-character names supported? \ > Why not std::wstring or even a templated type?" Sure, I read that, too. But even when using 'char' file names, on Windows that could be UTF-8, and they would then convert to/from UTF-16 in the implementation and use the wide character versions of the Win32 API. Currently the 'char' names they use on Windows are in the system codepage (as is the names passed to/from the C library's "normal" functions). Did anybody check whether the boost implementation handles double-byte characters correctly? Remember that if you use "codepage" names, at least the Japanese codepage 932 has double-byte characters where the second byte is a backslash. I.e. doing stuff like strchr(filename, '\\') when parsing pathnames is broken. With UTF-8, there is no such problem, and you then get the additional benefit that on all machines you can handle all characters, not just those in the system codepage. --tml |
From: Jonathan T. <tec...@ka...> - 2005-01-05 21:40:54
|
Greg Chicares wrote: > On 2004-12-31 10:08 PM, Tor Lillqvist wrote: > >> >> I find it a bit sad that something as new and designed-from-scratch >> like boost doesn't use the wide-character API on Windows. I understand >> that they don't want to provide a wide-character API for boost itself, >> but they should IMHO internally use wide-character APIs and then >> take/return UTF-8 in the boost API. Boost.Filesystem was designed with standardization in mind. This means that careful consideration had to be given to portability across as many platforms with a C++ implementation as possible. At the time the initial version was written, it wasn't clear how to handle wide-character file names. Since the initial release there has been extensive discussion of wide character support, and it was decided some time ago to add it. Beman Dawes is working on this issue right now. Jonathan |
From: Aaron W. L. <aar...@aa...> - 2005-01-04 16:33:04
|
Tor Lillqvist wrote: > Paul Grenyer writes: > > If you want cross-platform and you're prepared to go to C++ then I believe > > the boost (www.boost.org) file library will do what you want. > > I find it a bit sad that something as new and designed-from-scratch > like boost doesn't use the wide-character API on Windows. I understand > that they don't want to provide a wide-character API for boost itself, > but they should IMHO internally use wide-character APIs and then > take/return UTF-8 in the boost API. Boost.Filesystem is currently being redesigned. There have been several threads lately on the Boost mailing lists discussing substantial revisions to the present interface, including wide character support on Windows. I hope that a future final form of the interface will differ considerably from the present interface. Aaron W. LaFramboise |
From: Peter B. S. <wyo...@ac...> - 2004-12-31 23:29:06
|
On Fri, 2004-12-31 at 14:20, Jason Benjamin wrote: > I'm trying to delve into more complex C programming. > I want to know how to use io.h (linked to by dir.h) > for functions such as findfirst and so on with the > purpose of creating programs that can search for files > or perhaps perform like ls/dir. As John said, this is certainly OS-specific. Not only are the higher-level functions such as renaming and moving OS-specific, even the format of the directory tree varies from platform to platform. Consider how different the output of "ls -l" is vs. the DOS dir command... half the information that ls returns isn't even available to DOS. With MingW, you would probably want to use the FindFirstFile and FindNextFile functions from the API. If you like, email me privately and I'll send you a file copying program I wrote as an exercise. It doesn't do much (if anything) more than XCOPY *.* /S does, but I just did it as an exercise to learn how to traverse directory trees and manipulate files. ------- Peter B. Steiger Cheyenne, WY |
From: Tor L. <tm...@ik...> - 2005-01-01 01:42:46
|
Ome thing you definitely should take into consideration from the start if you intend your code to be more than a "toy", is that on Windows, the actual file names in the file systems are in Unicode. You *should* use the wide character versions of the dirent functions. Using the normal (system codepage) versions does mean that your code won't be able to see all file names that can be present on a system, viz. file names containing characters not in the system codepage. (For instance, on a US or Western European machine, file names with Greek or Cyrillic characters in them.) Ignoring these issues might mean that the majority of the World will ignore your software ;-) (You can wrap the wide character dirent funtions and convert the wchar_t strings back and forth into UTF-8 so that the rest of your code only sees char strings on Windows, too.) --tml |
From: Greg C. <chi...@co...> - 2005-01-01 02:09:39
|
On 2004-12-31 4:20 PM, Jason Benjamin wrote: > I'm trying to delve into more complex C programming. > I want to know how to use io.h (linked to by dir.h) > for functions such as findfirst and so on with the > purpose of creating programs that can search for files > or perhaps perform like ls/dir. The source for gnu utilities like 'ls' might show how to do that. Try a mirror like http://ftp.hol.gr/mirror/gnu/coreutils/ and see whether they compile for the msw platform out of the box, for a compiler whose standard library offers <dirent.h>. If they don't, then compare the gnu sources to a windows ports such as MinGW MSYS to see what needs to be changed. > I have found a few > examples that work. One is Windows API, but I'm not > trying to do this with Windows API. The other uses > dirent.h. The <dirent.h> version may already be what you want. Try the sample program at the bottom of this email; it works on msw with MinGW gcc. Other compilers may lack library support for the posix functions. > I've heard that this sort of thing is very > compiler/OS specific, so once I have this figured out > for GCC, there shouldn't be anymore problems. That depends on exactly what you need to do. Even though you have a common API, what actually happens depends on the platform. For instance, msw doesn't have symlinks, and its filesystem has multiple roots. > I am > slightly confused on how to declare and deal with the > struct involved. There's a trivial <dirent.h> example below, and more advanced examples can be found online if you determine that meets your needs. > Finally, how easily would this directory parsing > routine port to another OS or processor. That depends on the other OS; it may not even have a filesystem. > I'd appreciate any advice. Thanks. Take a look at http://boost.org/libs/filesystem/doc/index.htm It's C++ and you specified C, but internally it's just calling C library routines for different platforms. This was carefully written and reviewed by people on the C++ committee for possible inclusion in a future standard. The documentation and inline comments discuss the issues and point out pitfalls. Here's a C example adapted from the BSD docs; it compiles with MinGW: #include <dirent.h> #include <stdio.h> int main(int argc, char* argv[]) { char* name; int len; DIR* dirp; struct dirent* dp; name = argv[1]; len = strlen(name); dirp = opendir("."); if (dirp != NULL) { while ((dp = readdir(dirp)) != NULL) if (dp->d_namlen == len && !strcmp(dp->d_name, name)) { (void)closedir(dirp); printf("Found '%s'\n", name); return 0; } (void)closedir(dirp); } printf("Didn't find '%s'\n", name); return 1; } Sample run (*nix shell running under msw): C:/tmp[1]$./a dirent.c Found 'dirent.c' C:/tmp[0]$./a abcdefg Didn't find 'abcdefg' C:/tmp[1]$ |
From: John G. <jo...@jo...> - 2005-01-01 05:10:59
|
Tor Lillqvist wrote: > Ome thing you definitely should take into consideration from the > start if you intend your code to be more than a "toy", is that on > Windows, the actual file names in the file systems are in Unicode. I know Windows NT/2000/XP/etc use Unicode in the kernel, but I thought the file system was still ASCII. Either way, I think the majority of files use the lower 7 bits of Unicode, which is ASCII anyway. -- John Gaughan http://www.johngaughan.net/ jo...@jo... |
From: Tor L. <tm...@ik...> - 2005-01-01 15:53:41
|
John Gaughan writes: > I know Windows NT/2000/XP/etc use Unicode in the kernel, but I thought > the file system was still ASCII. Certainly not. It is UTF-16. (NTFS, that is, not FAT*.) > Either way, I think the majority of files use the lower 7 bits of > Unicode, which is ASCII anyway. So what? Even if just a very small part of the files on the World's Windows machines have file names that can't be expressed in the machine's system codepage, is that a reason to ignore them, in a library that is supposed (?) to be well-designed from scratch without any backward compatibility baggage? --tml |
From: Robb B. <Rob...@gm...> - 2005-01-01 18:29:36
|
Jason Benjamin schrieb: >I'm trying to delve into more complex C programming. > Good luck ;-) >I want to know how to use io.h (linked to by dir.h) >for functions such as findfirst and so on with the >purpose of creating programs that can search for files >or perhaps perform like ls/dir. > Is there a special reason why you want to use io.h? What about opendir(), readdir() and so on in stdio.h or fstat()? AFAIK do they also work on Windows, only the stat family is different from unix. >I have found a few examples that work. One is Windows API, but I'm not >trying to do this with Windows API. > Good idea, since this might change in future (with dot crap) and is not portable. >The other uses dirent.h. > Oh, that I meant above. Sorry for the typo (stdio.h). >I've heard that this sort of thing is very compiler/OS specific, so once I have this figured out for GCC, there shouldn't be anymore problems. I am >slightly confused on how to declare and deal with the struct involved. > > AFAIK it is only recommended using the d_name member, since this is the only OS/compiler independent one in the dirent struct. Using this struct is very simple: DIR *dir_handle; struct dirent *ent; if (! (dir_handle = opendir(dir_name))) return could_not_open(dir_name); while ((ent = readdir(dir_handle))) { do_something_with(ent); or_with(ent->d_name); } closedir(dir_handle); >Finally, how easily would this directory parsing routine port to another OS or processor. > > I think it depends on how specific dirent is. >I'd appreciate any advice. Thanks. > >Jason Benjamin > > HTH, -- Robert Bienert <robertbienert[AT]gmx[dot]net> http://www.rbprogs.de.vu/ - some free and open source stuff http://applaunch.sf.net/ - a graphical command line for MacOS X http://www.robertbienert.de/ - my personal homepage |
From: Benjamin R. <Ben...@ep...> - 2005-01-02 11:45:17
|
Hi Tor, > John Gaughan writes: > > I know Windows NT/2000/XP/etc use Unicode in the kernel, but I > > thought the file system was still ASCII. Tor Lillqvist writes: > Certainly not. It is UTF-16. (NTFS, that is, not FAT*.) The FAT disk format uses UTF-16 since Windows 95 (long file names). NT-based systems fully support that. benny |
From: Tor L. <tm...@ik...> - 2005-01-02 14:00:34
|
Benjamin Riefenstahl writes: > The FAT disk format uses UTF-16 since Windows 95 (long file names). > NT-based systems fully support that. Didn't know that. I stand corrected. --tml |
From: Benjamin R. <Ben...@ep...> - 2005-01-02 11:57:22
|
Hi Jason, Jason Benjamin writes: > for functions such as findfirst and so on findfirst() is a DOS API that is emulated by the C runtime library on Windows. You may want to jump straight to the equivalent native Windows API FindFirstFile() or FindFirstFileEx(). See MSDN <http://msdn.microsoft.com/library/en-us/fileio/base/findfirstfile.asp> for documentation and even example code. > The other uses dirent.h. I've heard that this sort of thing is very > compiler/OS specific, opendir()/readdir()/closedir() is the standard POSIX (Unix) API. This is also emulated by the C runtime library on Windows (in all compilers that I know). So this is more portable than FindFirstFile(). For some specific uses the opendir() method is slower, because FindFirstFile[Ex]() has some built-in features that opendir() doesn't have. benny |
From: Tor L. <tm...@ik...> - 2005-01-02 13:53:22
|
Benjamin Riefenstahl writes: > opendir()/readdir()/closedir() is the standard POSIX (Unix) API. > This is also emulated by the C runtime library on Windows (in all > compilers that I know). No, it isn't. The Microsoft C runtime or compiler doesn't provide this API. Mingw has it in its "mingwex" library. I don't know about the other commercial compilers. Technically, there is no reason why the same dirent implementation as in mingwex couldn't be built by and for the Microsoft compiler (and presumably other commercial compilers, too), but I don't think it's very widespread outside the mingw OpenSource-ish community, for some reason. --tml |
From: Gisle V. <gi...@bg...> - 2005-01-02 14:05:44
|
"Tor Lillqvist" wrote: > No, it isn't. The Microsoft C runtime or compiler doesn't provide this > API. Mingw has it in its "mingwex" library. I don't know about the > other commercial compilers. Watcom, Digital Mars has it too. But not MSVC nor Lcc-Win. --gv |
From: Benjamin R. <Ben...@ep...> - 2005-01-03 09:40:18
|
Hi Tor, > Benjamin Riefenstahl writes: > > opendir()/readdir()/closedir() is the standard POSIX (Unix) API. > > This is also emulated by the C runtime library on Windows (in > > all compilers that I know). Tor Lillqvist writes > No, it isn"t. The Microsoft C runtime or compiler doesn"t provide > this API. Mingw has it in its "mingwex" library. [...] Ah, you are right. Sorry about the my misinformation here. That shows how long I haven't used VC ;-) It should by a nearly trivial project to implement the POSIX API on top of FindFirstFile(), though, so maybe that is still a usefull direction to pursue. benny |
From: Earnie B. <ea...@us...> - 2005-01-03 13:05:03
|
<quote who="Benjamin Riefenstahl"> > Hi Tor, > >> Benjamin Riefenstahl writes: >> > opendir()/readdir()/closedir() is the standard POSIX (Unix) API. >> > This is also emulated by the C runtime library on Windows (in >> > all compilers that I know). > > Tor Lillqvist writes >> No, it isn"t. The Microsoft C runtime or compiler doesn"t provide >> this API. Mingw has it in its "mingwex" library. [...] > > Ah, you are right. Sorry about the my misinformation here. That > shows how long I haven't used VC ;-) > > It should by a nearly trivial project to implement the POSIX API on > top of FindFirstFile(), though, so maybe that is still a usefull > direction to pursue. > Why develop it again, why not just use the code in mingwex? Earnie -- http://www.mingw.org http://sourceforge.net/projects/mingw https://sourceforge.net/donate/index.php?user_id=15438 |