Open a file at runtime

Discussion in 'C Programming' started by Frank, Jun 17, 2005.

  1. Frank

    Frank Guest

    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?
    Frank, Jun 17, 2005
    #1
    1. Advertising

  2. Frank

    Michael Mair Guest

    Frank wrote:
    > 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
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Jun 17, 2005
    #2
    1. Advertising

  3. Frank

    Frank Guest

    > > 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
    Frank, Jun 18, 2005
    #3
  4. On Fri, 17 Jun 2005 07:07:12 +0200, Michael Mair
    <> wrote:

    <snip>
    > 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
    Dave Thompson, Jun 27, 2005
    #4
  5. > From: "Frank" <>
    > 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.
    Robert Maas, see http://tinyurl.com/uh3t, Jun 28, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. THY
    Replies:
    4
    Views:
    512
    Gönen EREN
    Aug 22, 2003
  2. ml
    Replies:
    0
    Views:
    1,450
  3. ml
    Replies:
    2
    Views:
    4,850
    John C. Bollinger
    Nov 30, 2004
  4. Hal Vaughan
    Replies:
    11
    Views:
    1,107
    Gordon Beaton
    May 22, 2006
  5. Schüle Daniel

    File::open and File.open

    Schüle Daniel, Oct 23, 2006, in forum: Ruby
    Replies:
    4
    Views:
    188
    Rick DeNatale
    Oct 24, 2006
Loading...

Share This Page