Open a file at runtime

F

Frank

Could someone tell me how to open a file at run time
that I didn't know the name of at compile time?
I know how to open a file at compile time when I know
what the name is going to be.

FILE *p_afile;

if((p_afile = fopen("shoppinglist.txt", "r")) == NULL)
{
fprint("Could not open file");
}

However, lets say I ask the user what file he wants
to open and he types in a name like NFLteams. I put
that name into maybe a char type variable then
what is the syntax to open it?
 
M

Michael Mair

Frank said:
Could someone tell me how to open a file at run time
that I didn't know the name of at compile time?
I know how to open a file at compile time when I know
what the name is going to be.

FILE *p_afile;

if((p_afile = fopen("shoppinglist.txt", "r")) == NULL)
{
fprint("Could not open file");

fprint is no standard C function; you probably mean
printf(....) or fprintf(stderr,....);
}

However, lets say I ask the user what file he wants
to open and he types in a name like NFLteams. I put
that name into maybe a char type variable then
what is the syntax to open it?

Let's look at the prototype of fopen():

FILE *fopen (const char *filename, const char *mode);

So, you need your file name at runtime in an object
that fits the description of filename. This can be
a string literal (as above) or an array of char
containing a C string or a char * pointing to a C
string; however it cannot be a "char type variable",
as this gives no C string but a single char.

So, we could have
#define NAMELEN 80
.....
char buf[NAMELEN+1];
....
/* get filename of length <= NAMELEN from user and store it in buf */
....
p_afile = fopen(buf, "r");
if (p_afile == NULL) {
....

or
int main (int argc, char **argv)
{
char *filename;
....
if (argc <= 1)
filename = "default"; /* Note: we are _not_ copying
"default" anywhere but let filename
point at the start of default. */
else
filename = argv[1];
....
p_afile = fopen(filename, "r");
....
}
or
char *filename;
....
/* allocate storage for filename and read file name into filename */
....
p_afile = fopen(filename, "r");
....

For how to read in user input, have a look at the comp.lang.c FAQ


Cheers
Michael
 
F

Frank

fprint("Could not open file");
fprint is no standard C function; you probably mean
printf(....) or fprintf(stderr,....);


Yes, Michael you are correct; I wanted to type "fprintf(" but the hour
being late and my fingers needing sleep seemed to have resulted in
not hitting the 'f' key hard enough.
Thanks for answering my question of how to handle an unknown
file name at compile time. The one dimensional char array variable
is something I can understand and I am going to type it into my
compiler right now and see what happens.
Frank
 
D

Dave Thompson

On Fri, 17 Jun 2005 07:07:12 +0200, Michael Mair

char buf[NAMELEN+1];
....
/* get filename of length <= NAMELEN from user and store it in buf */
....
p_afile = fopen(buf, "r");
if (p_afile == NULL) {
....

And to forestall the OP's next question(s):

Don't use gets() to read the filename into buf, at least not if anyone
else will ever give input to your program: they can make it overrun
your buffer and at minimum crash your program; on many systems
depending on their skill they can do much more extensive damage.

fgets() prevents this (if used sanely) but unlike gets() it includes
in the value stored the newline ending the input line if not overlong.
You almost certainly don't want that newline in your filename -- on
some systems it is flat illegal, and on others a Very Very Bad Idea.
So check for it and remove it before using buf for the fopen() call.

- David.Thompson1 at worldnet.att.net
 
R

Robert Maas, see http://tinyurl.com/uh3t

From: "Frank said:
Could someone tell me how to open a file at run time

You were already doing that, but didn't realize it.
that I didn't know the name of at compile time?

I'll get to that later.
I know how to open a file at compile time ...

No you don't. You are quite confused!
If the file were opened at compile time, then if you compile the
program then replace the data file with a new version the compiled
program would still be using the old data from before the program was
compiled instead of the new data you put in the file later. Think about
it.
... fopen("shoppinglist.txt", "r") ...
That does *not* open the file at compile time! Here's what happens:
You specify the file name as a string literal at compile time.
At that time the file doesn't even have to exist yet.
The string literal is compiled into the program, and written into
object file, and later passed to the loader.
The fopen call is compiled, with pointer to that string literal,
written into object file, and later passed to loader too.
(The object file might be virtual, or deleted shortly, so you might
never really see it.)
The loader reads in the object file and builds the runnable. Even now
the data file doesn't yet have to exist.

When you try to run the program, i.e. you invoke the runnable, the code
for the literal and the code for the fopen call are brought into
memory, then the pointer to the literal is put in a register or on the
stack and control is passed to fopen. Even now the file doesn't have to
yet exist, but suddenly the innerds of fopen look for the file and
*now* the file must exist and *now* the file is finally being opened.

Suppose you create a data file by some other name, don't rename it
to the correct name yet. Also, you put a sleep for five seconds
in the program just before the fopen. Something like this:
printf("Sleeping...\n");
...code to sleep...
printf("done, going ahead with fopen...\n");
...fopen...
Now when you run that program you wait until it says Sleeping.., and
*then* you quickly rename the file to have the correct name, and the
program works fine.

Another experiment: Have correct name, but while program is
sleeping you rename file to have wrong name. Now program bombs out
due to not finding the file where it's supposed to be.

These experimetns prove the file isn't opened until runtime after the
sleeping is finished. It isn't even opened at the time the runnable is
started! Not until later when execution reaches the point in sequence
where the fopen is called.

This differs from FORTRAN IV an old IBM 360/370 batch system where all
files are opened at the time the program is started, before any
executable statements in the program have been run! Do you remember way
back then?

Back to your question: Don't use a string literal, use a char* pointer
or char[...] array that you fill with characters of filename just
before you call fopen.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top