Problem with FCLOSE

Discussion in 'C Programming' started by Marcus Jacobs, Aug 5, 2003.

  1. Dear Group

    I have encountered a problem with fclose and I am wondering if anyone
    could provide some insight about this problem to me. Currently, I am
    working on a small personal project that is requiring for me to alter
    some existing code to a program. While running the unaltered code, I
    kept encountering an application (The exception unknown software
    exception(0xc00000fd) etc. .. etc... etc... I am running W2K Pro).
    Through a bit of debugging I singled out where the problem is
    occuring. It is occuring when it attemps to close a file that had
    previously been open. While tinkering with this problem, I noticed
    that no error occured while closing when I manually entered the file
    name into the source code. The error only occured when the user has to
    key-in the file name from a command line (this is how I wish for the
    program to run). What is causing this problem? Below I have provided
    some source code to the function that is causing the problem. Here is
    the version of the source in which no error occurs. I have set the
    string, finc_name, to the file name "all.inc". Normally, the array is
    set to a default of size 80 similar to fpov_name. I have also
    commented out the portion of the code which prompts the user to key-in
    the file name.

    Thanks


    Marcus D. Jacobs






    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    #include "numtypes.h"
    /* #include "numtable.h"*/

    typedef struct
    {
    Word x,r,g,b;
    } colorinfo;


    FILE *finc, *fpov, *frad;
    char ch, frad_name[80], finc_name[] = "all.inc", fpov_name[80] ,
    is_num;
    char *pov_word;
    char chpov , colorend='f';
    colorinfo color;
    Word texture[2600];


    void reads_triangle(Word pov_num);
    void reads_smoothtriangle(Word pov_num);
    void reads_inc(void);
    void reads_color(void);
    void reads_texture(void);



    main(void)
    {
    int m=1, n, j;
    char chtext, finish;
    char *inc_word;
    int isize;

    int j2;

    /*
    printf("Enter POV include file name ( *.inc ) : ");
    gets(finc_name);
    printf("\n");
    */

    finc=fopen(finc_name, "r");
    chtext = getc(finc);

    if (finc==NULL)
    { printf(" Can't open %s\n", finc);
    exit(EXIT_FAILURE);
    }
    while (chtext != EOF )
    {
    finish ='f';
    if ( ( inc_word = malloc(25)) == NULL )
    { printf("Out of memory");
    exit(EXIT_FAILURE);;
    }
    while (isspace(chtext)) chtext = getc(finc);
    j=0;
    while (chtext != EOF && isspace(chtext) == 0)
    { inc_word[j++] = chtext;
    chtext = getc(finc);
    }

    inc_word[j] = '\0';

    if (strcmp(inc_word, "texture") == 0 && finish == 'f')
    { while (isspace(chtext)) chtext = getc(finc);
    n=0;
    chtext = getc(finc);
    while ( chtext != '}' )
    {
    texture[m][n++] = chtext;
    chtext = getc(finc);
    }
    texture[m][n] = '\0';
    /* printf(" texture = %s ", texture[m]);*/
    m++;
    finish = 't';
    }
    free(inc_word);
    }

    fclose(finc);
    }
     
    Marcus Jacobs, Aug 5, 2003
    #1
    1. Advertising

  2. Marcus Jacobs

    Eric Sosman Guest

    Marcus Jacobs wrote:
    > [...]
    > char ch, frad_name[80], finc_name[] = "all.inc", fpov_name[80] ,
    > [...]
    > gets(finc_name);


    Here's at least one problem; there may be others. The
    `finc_name' array is only eight characters long, so it can't
    hold a string any longer than seven characters plus the
    terminating '\0'. If the user types a longer name, the extra
    characters won't fit in the array, and will most likely stomp
    all over the nearby memory. What happens next is unpredictable,
    but is unlikely to be a Happy Experience.

    By the way, don't use gets(). See Question 12.23 in the
    comp.lang.c Frequently Asked Questions (FAQ) list

    http://www.eskimo.com/~scs/C-faq/top.html

    --
     
    Eric Sosman, Aug 5, 2003
    #2
    1. Advertising

  3. Marcus Jacobs

    Mark Gordon Guest

    On 5 Aug 2003 14:53:20 -0700
    (Marcus Jacobs) wrote:

    > Dear Group
    >
    > I have encountered a problem with fclose and I am wondering if anyone
    > could provide some insight about this problem to me. Currently, I am
    > working on a small personal project that is requiring for me to alter
    > some existing code to a program. While running the unaltered code, I
    > kept encountering an application (The exception unknown software
    > exception(0xc00000fd) etc. .. etc... etc... I am running W2K Pro).
    > Through a bit of debugging I singled out where the problem is
    > occuring. It is occuring when it attemps to close a file that had
    > previously been open. While tinkering with this problem, I noticed
    > that no error occured while closing when I manually entered the file
    > name into the source code. The error only occured when the user has to
    > key-in the file name from a command line (this is how I wish for the
    > program to run). What is causing this problem? Below I have provided
    > some source code to the function that is causing the problem. Here is
    > the version of the source in which no error occurs. I have set the
    > string, finc_name, to the file name "all.inc". Normally, the array is
    > set to a default of size 80 similar to fpov_name. I have also
    > commented out the portion of the code which prompts the user to key-in
    > the file name.
    >
    > Thanks
    >
    >
    > Marcus D. Jacobs
    >
    >
    >
    >
    >
    >
    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <ctype.h>
    > #include <string.h>
    > #include "numtypes.h"
    > /* #include "numtable.h"*/
    >
    > typedef struct
    > {
    > Word x,r,g,b;
    > } colorinfo;
    >
    >
    > FILE *finc, *fpov, *frad;
    > char ch, frad_name[80], finc_name[] = "all.inc", fpov_name[80] ,
    > is_num;
    > char *pov_word;
    > char chpov , colorend='f';
    > colorinfo color;
    > Word texture[2600];

    You have not shown us the definition of Word, so we don't know what type
    texture is.
    >
    >
    > void reads_triangle(Word pov_num);
    > void reads_smoothtriangle(Word pov_num);
    > void reads_inc(void);
    > void reads_color(void);
    > void reads_texture(void);
    >
    >
    >
    > main(void)

    int main(void)

    > {
    > int m=1, n, j;
    > char chtext, finish;
    > char *inc_word;
    > int isize;
    >
    > int j2;
    >
    > /*
    > printf("Enter POV include file name ( *.inc ) : ");
    > gets(finc_name);

    When this is uncommented, if the user enters a file name longer than the
    buffer you have just blown up your program.

    > printf("\n");
    > */
    >
    > finc=fopen(finc_name, "r");
    > chtext = getc(finc);

    Surely this should be after you've checked the open worked? Otherwise
    *BANG*

    > if (finc==NULL)
    > { printf(" Can't open %s\n", finc);
    > exit(EXIT_FAILURE);
    > }
    > while (chtext != EOF )

    EOF might not fit in a char so chtext should have been declared as an
    int rather than a char.

    > {
    > finish ='f';
    > if ( ( inc_word = malloc(25)) == NULL )
    > { printf("Out of memory");
    > exit(EXIT_FAILURE);;
    > }
    > while (isspace(chtext)) chtext = getc(finc);
    > j=0;
    > while (chtext != EOF && isspace(chtext) == 0)
    > { inc_word[j++] = chtext;
    > chtext = getc(finc);
    > }
    >
    > inc_word[j] = '\0';

    If a 25 character (or longer) word was entered you've just blown things
    up again. You might want to either limit the above loop or use realloc.

    > if (strcmp(inc_word, "texture") == 0 && finish == 'f')
    > { while (isspace(chtext)) chtext = getc(finc);
    > n=0;
    > chtext = getc(finc);
    > while ( chtext != '}' )
    > {
    > texture[m][n++] = chtext;
    > chtext = getc(finc);
    > }

    Again, not check on going passed the end of the array. Also you are not
    checking to see if getc succeeds.

    > texture[m][n] = '\0';
    > /* printf(" texture = %s ", texture[m]);*/
    > m++;
    > finish = 't';
    > }
    > free(inc_word);
    > }
    >
    > fclose(finc);
    > }


    There are probably other errors with the program, I could not be
    bothered to check it carefully since it is so bad. I would also suggest
    checking the FAQ for comp.lang.c (google will find it) for the correct
    way to handle checking the results of file operations and probably
    almost everything else in the program.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Aug 5, 2003
    #3
  4. Marcus Jacobs

    -berlin.de Guest

    Marcus Jacobs <> wrote:
    > I have encountered a problem with fclose and I am wondering if anyone
    > could provide some insight about this problem to me. Currently, I am
    > working on a small personal project that is requiring for me to alter
    > some existing code to a program. While running the unaltered code, I
    > kept encountering an application (The exception unknown software
    > exception(0xc00000fd) etc. .. etc... etc... I am running W2K Pro).
    > Through a bit of debugging I singled out where the problem is
    > occuring. It is occuring when it attemps to close a file that had
    > previously been open. While tinkering with this problem, I noticed
    > that no error occured while closing when I manually entered the file
    > name into the source code. The error only occured when the user has to
    > key-in the file name from a command line (this is how I wish for the
    > program to run). What is causing this problem? Below I have provided
    > some source code to the function that is causing the problem. Here is
    > the version of the source in which no error occurs. I have set the
    > string, finc_name, to the file name "all.inc". Normally, the array is
    > set to a default of size 80 similar to fpov_name. I have also
    > commented out the portion of the code which prompts the user to key-in
    > the file name.



    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <ctype.h>
    > #include <string.h>
    > #include "numtypes.h"
    > /* #include "numtable.h"*/


    > typedef struct
    > {
    > Word x,r,g,b;
    > } colorinfo;



    > FILE *finc, *fpov, *frad;
    > char ch, frad_name[80], finc_name[] = "all.inc", fpov_name[80] ,
    > is_num;
    > char *pov_word;
    > char chpov , colorend='f';
    > colorinfo color;
    > Word texture[2600];



    > void reads_triangle(Word pov_num);
    > void reads_smoothtriangle(Word pov_num);
    > void reads_inc(void);
    > void reads_color(void);
    > void reads_texture(void);


    > main(void)


    int main( void )

    since main() is supposed to return an int.

    > {
    > int m=1, n, j;
    > char chtext, finish;
    > char *inc_word;
    > int isize;


    > int j2;


    > /*
    > printf("Enter POV include file name ( *.inc ) : ");


    You better add here

    fflush( stdout );

    or the user may not see the request.

    > gets(finc_name);


    Never, ever use gets(). You will never be able to ascertain that the
    user does not enter a file name that's longer than the length of the
    buffer you supply. Use fgets().

    > printf("\n");
    > */


    > finc=fopen(finc_name, "r");
    > chtext = getc(finc);
    >
    > if (finc==NULL)
    > {
    > printf(" Can't open %s\n", finc);
    > exit(EXIT_FAILURE);
    > }


    You need to check if fopen() was successful *before* you call getc().
    And you must make 'chtext' an int, not a char. Otherwise you won't be
    able to check for EOF. EOF is a return value of getc() that can't be
    stored in a char.

    > while (chtext != EOF )
    > {
    > finish ='f';
    > if ( ( inc_word = malloc(25)) == NULL )
    > {
    > printf("Out of memory");
    > exit(EXIT_FAILURE);;
    > }
    > while (isspace(chtext)) chtext = getc(finc);


    What is supposed to happen when getc() returns EOF, e.g. because the
    input file is broken and does not look like you expect it?

    > j=0;
    > while (chtext != EOF && isspace(chtext) == 0)
    > {
    > inc_word[j++] = chtext;
    > chtext = getc(finc);
    > }


    You never check that you don't get more than 24 characters in a row.
    If this happens you write past the end of the memory you allocated.

    > inc_word[j] = '\0';
    >
    > if (strcmp(inc_word, "texture") == 0 && finish == 'f')
    > {
    > while (isspace(chtext)) chtext = getc(finc);
    > n=0;
    > chtext = getc(finc);
    > while ( chtext != '}' )
    > {
    > texture[m][n++] = chtext;


    'texture' is declared as an array of 'Word' (whatever that's supposed
    to be). Unless 'Word' is some kind of array (of chars?) and not just a
    pointer to an array this looks fishy, to say the least. Even assuming
    that 'Word' is typedef'ed to be an array of chars you don't check that
    you don't write past its end. And if you do anything can happen.

    Finally, since you start with m = 1, why don't you want to use the
    first element of 'texture'?

    > chtext = getc(finc);
    > }
    > texture[m][n] = '\0';
    > /* printf(" texture = %s ", texture[m]);*/
    > m++;
    > finish = 't';
    > }


    And you also don't make sure that you don't read more elements into
    'texture' than the 2600 'Word's you declared.

    > free(inc_word);
    > }
    >
    > fclose(finc);


    You probably have been written into some memory you don't own,
    overwriting some important structure for the file pointer. And
    now you get what you deserve ;-) You might be unlucky in not
    getting an error when you comment out the stuff for getting
    the file name from the user because of a different layout of
    the executable. But that does not mean that your program is
    correct.

    > }


    And finally you're missing returning an int.

    Regards, Jens
    --
    _ _____ _____
    | ||_ _||_ _| -berlin.de
    _ | | | | | |
    | |_| | | | | | http://www.physik.fu-berlin.de/~toerring
    \___/ens|_|homs|_|oerring
     
    -berlin.de, Aug 5, 2003
    #4
  5. Marcus Jacobs wrote:

    > [...]
    > { printf(" Can't open %s\n", finc);
    > [...]


    In addition to the other hints already given you probably want to use
    { printf(" Can't open %s\n", finc_name);

    Additionally most times it's wise to write this information to standard
    error:
    { fprintf(stderr," Can't open %s\n", finc_name);




    Andre
     
    Andre Hinrichs, Aug 6, 2003
    #5
  6. Marcus Jacobs

    -berlin.de Guest

    Marcus Jacobs <> wrote:

    Beside what Artie has been already told you (about removing the '\n'
    from the input) there are still several things that won't work:

    > #include <stdio.h>
    > #include <stdlib.h>
    > #include <ctype.h>
    > #include <string.h>
    > #ifndef NUMTYPES_H
    > #define NUMTYPES_H


    > #define MAX_WORD_LEN 20
    > typedef char Word[MAX_WORD_LEN+1] ;


    > #endif


    Where's the #if (or similar) for this #endif?

    > typedef struct
    > {
    > Word x,r,g,b;
    > } colorinfo;



    > FILE *finc, *fpov, *frad;
    > char ch, frad_name[80], finc_name[80], fpov_name[80] , is_num;
    > char *pov_word;
    > char * finame;
    > char chpov , colorend='f';
    > colorinfo color;
    > Word texture[2600];



    > void reads_triangle(Word pov_num);
    > void reads_smoothtriangle(Word pov_num);
    > void reads_inc(void);
    > void reads_color(void);
    > void reads_texture(void);


    > int main(void)
    > {
    > int m=1, n, j;
    > char chtext, finish;
    > char *inc_word;
    > int j2;


    > printf("Enter POV include file name ( *.inc ) : ");
    > fgets(finc_name, 80, stdin);
    > printf("%s", finc_name);
    > printf("\n");


    > finc=fopen(finc_name, "r");


    > if (finc==NULL)
    > { printf(" Can't open %s\n", finc);
    > exit(EXIT_FAILURE);
    > }


    > chtext = getc(finc);


    > while (chtext != EOF )


    As long as you don't make 'chtext' an int you definitely will
    have only a near-to-zero chance of it being equal to EOF. EOF is
    typically an -1 *integer* (but don't rely on this, but you can
    rely on *not* being able to store it in a char). So the above
    comparison will nearly always fail and you never will stop looping.

    > {
    > finish ='f';
    > if ( ( inc_word = malloc(25)) == NULL )
    > { printf("Out of memory");
    > exit(EXIT_FAILURE);;
    > }
    > while (isspace(chtext)) chtext = getc(finc);


    When you reached the end of the file (and you can't detect it with
    'chtext' being a char) you just created an infinite loop because
    EOF is typically (int) -1. If you implicitely cast it to a char
    'chtext' is going to be a (char) -1 (or perhaps something else,
    e.g. a 255 if on your system chars are unsigned), at least it
    usually isn't going to be a white-space character.

    > j=0;
    > while (chtext != EOF && isspace(chtext) == 0)
    > { inc_word[j++] = chtext;
    > chtext = getc(finc);
    > }


    > inc_word[j] = '\0';


    Unless you are lucky you will end up with a sequence of more than
    24 non-whitespace characters and write past the end of the memory
    you allocated. In this case literally everything can happen. So
    *do* the checks or use a different language where you can't make
    these kinds of mistakes (you should think of using a lexer like
    lex or flex for these kinds of tasks anyway).

    > // printf("string are %s\n", inc_word);
    > if (strcmp(inc_word, "texture") == 0 && finish == 'f')
    > { while (isspace(chtext)) chtext = getc(finc);
    > n=0;
    > chtext = getc(finc);
    > while ( chtext != '}' )
    > {
    > texture[m][n++] = chtext;


    And here is the same problem: if you're unlucky enough there are
    going to be more than MAX_WORD_LEN characters not being '}' and
    you end up with writing over the end of texture[m] (and this looks
    like reading in a povray file where e.g. additional white-space
    characters are syntactically correct). It just takes a very small
    bit of care to avoid this, so why don't you just do it?

    > chtext = getc(finc);
    > }
    > texture[m][n] = '\0';
    > /* printf(" texture = %s ", texture[m]);*/
    > m++;


    How can you be that sure that you won't get more than 2599 of
    these texture strings? Checking is cheap and simple and avoids
    lots of unnecessary grief that comes from invoking undefined
    behavior.

    > finish = 't';
    > }
    > free(inc_word);
    > }
    >
    > fclose(finc);


    > return 0;
    > }

    Regards, Jens
    --
    _ _____ _____
    | ||_ _||_ _| -berlin.de
    _ | | | | | |
    | |_| | | | | | http://www.physik.fu-berlin.de/~toerring
    \___/ens|_|homs|_|oerring
     
    -berlin.de, Aug 7, 2003
    #6
  7. On Wed, 06 Aug 2003 21:57:48 GMT, Artie Gold <>
    wrote:

    >Marcus Jacobs wrote:

    snip
    >>
    >> printf("Enter POV include file name ( *.inc ) : ");
    >> fgets(finc_name, 80, stdin);

    >
    >You haven't stripped the newline ('\n') character.
    > *strstr(finc_name, "\n") = '\0';


    You need to make sure that fgets inserted a \n before you strip it.
    strstr can return NULL.

    snip


    <<Remove the del for email>>
     
    Barry Schwarz, Aug 7, 2003
    #7
  8. On 6 Aug 2003 14:23:58 -0700, (Marcus Jacobs)
    wrote:

    >Thanks everyone for all of your suggestions. I have revised some of
    >the source code (primarily getting rid of gets()). I have also
    >included here the definition of type WORD for everyone to view. The
    >other stuff I'll get to when I get this working properly. BTW, I am
    >compiling this with gcc included with MinGW. Similar issue arose when
    >I compiled this using MS Visual Studio. For starters, the problem that
    >I am encountering now is that even though fname_inc does list itself
    >as the filename given from fgets(), for some reason when I attempt to
    >fopen() a file with that name, it comes up NULL. Why does this happen.
    >In my case when I attempt to run the program I use a file named
    >"all.inc". As part of my debugging, I manually initialize the value of
    >fname_inc to "all.inc". When I do this, fopen() does work properly. I
    >can not understand why this program does not like to use any of the
    >data that is to be entered. As for the original problem with fclose(),
    >while debugging the program it seems to me that this isn't what is
    >causing the proble. The program works it way to the end and then at
    >the end the following error message is displayed:
    >
    >"The instruction at "0x77fcb03d" reference memory at "0x00000000". The
    >memory could not be "written"."
    >
    >I, for the life of me, can not figure out what is causing this. I do
    >like to post my questions to this ng but I do try very hard to fix
    >these problems myself before coming to everyone else. I am stuck. Here
    >is the source as I have revised it. If it would be helpful, I can post
    >a portion of the file "all.inc" to this ng such that someone may test
    >out the code. It is only an ASCII text file.
    >
    >
    >Thanks to everyone for your help.
    >
    >
    >Marcus
    >
    >#include <stdio.h>
    >#include <stdlib.h>
    >#include <ctype.h>
    >#include <string.h>
    >#ifndef NUMTYPES_H
    >#define NUMTYPES_H
    >
    >#define MAX_WORD_LEN 20
    >typedef char Word[MAX_WORD_LEN+1] ;
    >
    >#endif
    >
    >typedef struct
    >{
    > Word x,r,g,b;
    >} colorinfo;
    >
    >
    >FILE *finc, *fpov, *frad;
    >char ch, frad_name[80], finc_name[80], fpov_name[80] , is_num;
    >char *pov_word;
    >char * finame;
    >char chpov , colorend='f';
    >colorinfo color;
    >Word texture[2600];
    >
    >
    >void reads_triangle(Word pov_num);
    >void reads_smoothtriangle(Word pov_num);
    >void reads_inc(void);
    >void reads_color(void);
    >void reads_texture(void);
    >
    >
    >
    >int main(void)
    > {
    > int m=1, n, j;
    > char chtext, finish;
    > char *inc_word;
    > int j2;
    >
    > printf("Enter POV include file name ( *.inc ) : ");
    > fgets(finc_name, 80, stdin);


    If the data input by the user is less than 79 characters, fgets will
    include the \n (corresponding to the enter key) in the string. You
    need something like

    if ((inc_word = strchr(finc_name, '\n')) == NULL)
    /* error logic - you do not have the complete file name */
    else
    *inc_word = '\0';

    > printf("%s", finc_name);
    > printf("\n");
    >
    > finc=fopen(finc_name, "r");
    >
    > if (finc==NULL)
    > { printf(" Can't open %s\n", finc);


    This should be finc_name. finc is NULL and attempting to print what
    it points to invokes undefined behavior which may be the cause of your
    problem.

    > exit(EXIT_FAILURE);
    > }
    >
    > chtext = getc(finc);


    getc returns an int for a reason. You should respect that. It is
    entirely possible that EOF will not fit in a char.

    snip


    <<Remove the del for email>>
     
    Barry Schwarz, Aug 7, 2003
    #8
  9. Marcus Jacobs

    bd Guest

    On Wed, 06 Aug 2003 23:55:40 +0000, Jens.Toerrin wrote:

    > Marcus Jacobs <> wrote:
    >
    > Beside what Artie has been already told you (about removing the '\n'
    > from the input) there are still several things that won't work:
    >
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >> #include <ctype.h>
    >> #include <string.h>
    >> #ifndef NUMTYPES_H
    >> #define NUMTYPES_H

    >
    >> #define MAX_WORD_LEN 20
    >> typedef char Word[MAX_WORD_LEN+1] ;

    >
    >> #endif

    >
    > Where's the #if (or similar) for this #endif?


    Right below #include <string.h>.

    --
    Freenet distribution not available
    For every complex problem, there is a solution that is simple, neat, and wrong.
    -- H. L. Mencken
     
    bd, Aug 7, 2003
    #9
  10. Marcus Jacobs

    bd Guest

    On Wed, 06 Aug 2003 11:37:02 +0200, Andre Hinrichs wrote:

    > Marcus Jacobs wrote:
    >
    >> [...]
    >> { printf(" Can't open %s\n", finc);
    >> [...]

    >
    > In addition to the other hints already given you probably want to use
    > { printf(" Can't open %s\n", finc_name);
    >
    > Additionally most times it's wise to write this information to standard
    > error:
    > { fprintf(stderr," Can't open %s\n", finc_name);


    Better yet:
    {
    const static char *prefix = "Can't open ";
    char *buf = malloc(strlen(prefix) + strlen(finc_name) + 1);
    sprintf(buf, "%s%s", prefix, finc_name);
    perror(buf); /* Give more details on why the error occured */
    free(buf);

    --
    Freenet distribution not available
    They also surf who only stand on waves.
     
    bd, Aug 7, 2003
    #10
  11. Marcus Jacobs

    Artie Gold Guest

    Barry Schwarz wrote:
    > On Wed, 06 Aug 2003 21:57:48 GMT, Artie Gold <>
    > wrote:
    >
    >
    >>Marcus Jacobs wrote:

    >
    > snip
    >
    >>> printf("Enter POV include file name ( *.inc ) : ");
    >>> fgets(finc_name, 80, stdin);

    >>
    >>You haven't stripped the newline ('\n') character.
    >> *strstr(finc_name, "\n") = '\0';

    >
    >
    > You need to make sure that fgets inserted a \n before you strip it.
    > strstr can return NULL.
    >
    > snip
    >
    >
    > <<Remove the del for email>>


    Yup. You're absolutely correct, of course.
    I wasn't being as thorough as I should have been (but then I would have
    had to rewrite _everything_ for the OP ;-)).

    --ag

    --
    Artie Gold -- Austin, Texas
     
    Artie Gold, Aug 7, 2003
    #11
  12. Marcus Jacobs

    Chris Torek Guest

    [On issuing error messages after a failed fopen()]

    >On Wed, 06 Aug 2003 11:37:02 +0200, Andre Hinrichs wrote:
    >> Additionally most times it's wise to write this information to standard
    >> error:
    >> { fprintf(stderr," Can't open %s\n", finc_name);


    In article <-ip.org>
    bd <-ip.org> wrote:
    >Better yet:
    > const static char *prefix = "Can't open ";
    > char *buf = malloc(strlen(prefix) + strlen(finc_name) + 1);
    > sprintf(buf, "%s%s", prefix, finc_name);
    > perror(buf); /* Give more details on why the error occured */
    > free(buf);


    Much simpler, and more likely to work (malloc() might fail, and
    malloc() and sprintf() might overwrite errno, even on success --
    this is not entirely theoretical; real implementations really do
    overwrite errno on successful calls to fprintf(), for instance):

    fprintf(stderr, "cannot open %s for reading: %s\n", finc_name,
    strerror(errno));

    Here strerror(errno) grabs the value of errno before fprintf() can
    overwrite it, so that as long as fopen() sets errno based on the
    underlying reason the system was unable to open the supplied file,
    you will get a useful message, rather than -- as actually happens
    when fprintf() overwrites things -- something like:

    could not send mail to user@host: not a typewriter

    (The program that conspicuously produced this kind of error message
    was sendmail. "Well of course he's not a typewriter, what kind of
    stupid error is that?" :) )

    The drawback to using strerror() here is that the ANSI C standard
    (either one, C89 or C99) does not *require* systems to set errno
    on failure to open a file, and some systems sometimes do not. In
    this case, errno can be "left over" from a previous failure, so you
    may get messages like:

    cannot open foo.bar for reading: Numerical argument out of domain

    if the last errno was (say) EDOM. One can attempt to cure this by
    clearing errno before calling fopen, and using strerror(errno) only
    if errno is nonzero; or one can simply leave the interpretation up
    to the user:

    fprintf(stderr, "Cannot open %s for reading.\n"
    "The system's most recent reported error was %s, which\n"
    "is not necessarily the reason the open failed.\n",
    finc_name, strerror(errno));

    Or, of course, one can just restrict oneself to implementations that
    do always set errno appropriately. :)
    --
    In-Real-Life: Chris Torek, Wind River Systems (BSD engineering)
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://67.40.109.61/torek/index.html (for the moment)
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 7, 2003
    #12
    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. Anoop Nair
    Replies:
    1
    Views:
    482
    Victor Bazarov
    Aug 5, 2004
  2. VB
    Replies:
    3
    Views:
    5,256
    Ron Natalie
    Jan 15, 2005
  3. viza

    fclose(stdin);

    viza, Jul 19, 2003, in forum: C Programming
    Replies:
    0
    Views:
    451
  4. Trying_Harder

    fgets,fopen, fclose

    Trying_Harder, Aug 26, 2003, in forum: C Programming
    Replies:
    5
    Views:
    696
    John Bode
    Sep 3, 2003
  5. prama

    Re: Question about fopen, fput, fclose?

    prama, Aug 26, 2003, in forum: C Programming
    Replies:
    5
    Views:
    1,784
    Jack Klein
    Aug 28, 2003
Loading...

Share This Page