I'm programming in C and trying to write portable code.
My question is, how can I tell if a file exists and is readable?
I am currently using the code:
f = fopen(filename, "r");
if (f) printf("File exists!");
In my program, filename is set by the user, and should be considered as untrusted input (e.g. filename could be maliciously crafted).
My issue is that the above code is not robust. For example, when used on windows with the filename "PRN" it will print "File exists!" even though no such file exists on the filesystem.
I know I could filter out the reserved filenames on Windows, as there is only about a dozen of them, but that feels like a hack. Also, I only know what I know. Maybe there are other "reserved" or "special" names that I don't know about.
Is there any simple and portable way to determine if a file exists in C?
Alternatively, if I have to use an OS API, which function should I use?
For example, suppose we have a file called "Hello.txt", then checking if "hello.txt" or "heLLo.txt" exist should both return true.
If you're running Windows or any case-insensitive filesystem, then there's nothing to do but check one casing. If "Hello.txt" exists, then "hEllo.txt" exists (and is the same file) (the difficult problem here is when you want to make sure that the file is spelled with a given casing in the filesystem)
If you're running a case-sensitive filesystem, just take directory name of the current file, list file contents, and compare entries against the current filename, ignoring case.
Take a look at fcaseopen, which demonstrates how to handle case insensitive file operations.
Essentially, the C headers/functions to use are:
From dirent.h, use opendir/readdir/closedir to go thru the files in a directory
From string.h, use strcasecmp to compare two filesnames, ignoring the case of the characters
I currently have a short program to read and sort a text tile in C.
If I want to read many files, is there a substitute for:
FILE *f
f = fopen("*.txt", "rw");
Thanks in advance.
f = fopen("*.txt", "rw"); won't work in any case.
The usual way to do this probably depends on your operating system. On Unix-like systems, the simple way is to invoke your program with a command line like "my_pgm *.txt" and let the shell find the matching files. (You'll get multiple arguments, each one being a file name.) I understand that microsoft OSes would require the program to find the files itself.
To do that more or less portably, I'd probably use opendir() and readdir() to examine directory entries and see whether they matched the desired pattern.
I'm trying to use a system call to display the contents of a directory. I've been pointed in the direction of vfs_readdir, but I have no clue of how to use it or what to pass to it to get the contents of a directory. All I want to do is be able to list files in a directory similar to how ls works. (I eventually intend to store this in some sort of buffer, but for now just being able to print the contents of a dir would be enough).
I think you probably have to open the directory using filp_open.
For the "flags" argument, you proably need to put some combination of the LOOKUP_ flags listed in include/linux/namei.h
You can see what build_open_flags does here: http://lxr.linux.no/#linux+v3.1.5/fs/open.c#L876 to provide flags to filp_open.
As far as I know, filp_open IS the correct way of opening a file in kernel-space. However, doing so is discouraged.
Provided you do so from the context of a "normal" thread belonging to a user process, I think you will be ok.
just had a general question about how to approach a certain problem I'm facing. I'm fairly new to C so bear with me here. Say I have a folder with 1000+ text files, the files are not named in any kind of numbered order, but they are alphabetical. For my problem I have files of stock data, each file is named after the company's respective ticker. I want to write a program that will open each file, read the data find the historical low and compare it to the current price and calculate the percent change, and then print it. Searching and calculating are not a problem, the problem is getting the program to go through and open each file. The only way I can see to attack this is to create a text file containing all of the ticker symbols, having the program read that into an array and then run a loop that first opens the first filename in the array, perform the calculations, print the output, close the file, then loop back around moving to the second element (the next ticker symbol) in the array. This would be fairly simple to set up (I think) but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this? Not really asking for code ( unless there is some amazing function in c that will do this for me ;) ), just some advice from more experienced C programmers.
Thanks :)
Edit: This is on Linux, sorry I forgot to metion that!
Under Linux/Unix (BSD, OS X, POSIX, etc.) you can use opendir / readdir to go through the directory structure. No need to generate static files that need to be updated, when the file system has the information you want. If you only want a sub-set of stocks at a given time, then using glob would be quicker, there is also scandir.
I don't know what Win32 (Windows / Platform SDK) functions are called, if you are developing using Visual C++ as your C compiler. Searching MSDN Library should help you.
Assuming you're running on linux...
ls /path/to/text/files > names.txt
is exactly what you want.
opendir(); on linux.
http://linux.die.net/man/3/opendir
Exemple :
http://snippets.dzone.com/posts/show/5734
In pseudo code it would look like this, I cannot define the code as I'm not 100% sure if this is the correct approach...
for each directory entry
scan the filename
extract the ticker name from the filename
open the file
read the data
create a record consisting of the filename, data.....
close the file
add the record to a list/array...
> sort the list/array into alphabetical order based on
the ticker name in the filename...
You could vary it slightly if you wish, scan the filenames in the directory entries and sort them first by building a record with the filenames first, then go back to the start of the list/array and open each one individually reading the data and putting it into the record then....
Hope this helps,
best regards,
Tom.
There are no functions in standard C that have any notion of a "directory". You will need to use some kind of platform-specific function to do this. For some examples, take a look at this post from Cprogrammnig.com.
Personally, I prefer using the opendir()/readdir() approach as shown in the second example. It works natively under Linux and also on Windows if you are using Cygwin.
Approach 1) I would just have a specific directory in which I have ONLY these files containing the ticker data and nothing else. I would then use the C readdir API to list all files in the directory and iterate over each one performing the data processing that you require. Which ticker the file applies to is determined only by the filename.
Pros: Easy to code
Cons: It really depends where the files are stored and where they come from.
Approach 2) Change the file format so the ticker files start with a magic code identifying that this is a ticker file, and a string containing the name. As before use readdir to iterate through all files in the folder and open each file, ensure that the magic number is set and read the ticker name from the file, and process the data as before
Pros: More flexible than before. Filename needn't reflect name of ticker
Cons: Harder to code, file format may be fixed.
but I'd really like to avoid typing out over a thousand file names into a text file. Is there a better way to approach this?
I have solved the exact same problem a while back, albeit for personal uses :)
What I did was to use the OS shell commands to generate a list of those files and redirected the output to a text file and had my program run through them.
On UNIX, there's the handy glob function:
glob_t results;
memset(&results, 0, sizeof(results));
glob("*.txt", 0, NULL, &results);
for (i = 0; i < results.gl_pathc; i++)
printf("%s\n", results.gl_pathv[i]);
globfree(&results);
On Linux or a related system, you could use the fts library. It's designed for traversing file hierarchies: man fts,
or even something as simple as readdir
If on Windows, you can use their Directory Management API's. More specifically, the FindFirstFile function, used with wildcards, in conjunction with FindNextFile