no error by fscanf on reading from output file

Discussion in 'C Programming' started by V.Subramanian, India, Oct 30, 2011.

  1. This question is for learning purpose only.

    Consider the program sample.c :

    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>
    #include <string.h>

    int main()
    {
    errno = 0;

    FILE *fp = fopen("data.txt", "w");

    if (fp == NULL)
    {
    fprintf(stderr,
    "Could not open input file - data.txt\n%s\n",
    strerror(errno));

    return EXIT_FAILURE;
    }

    if (fprintf(fp, "test data") < 1)
    {
    fprintf(stderr,
    "could not write message into data.txt\n");

    return EXIT_FAILURE;
    }

    fflush(fp);

    int a;
    int b;

    errno = 0;

    // I deliberately try to read from the file
    // opened in 'write' mode
    if (fscanf(fp, "%d%d", &a, &b) == 2)
    {
    fprintf(stdout,
    "a = %d, b= %d\n",
    a,
    b);
    fflush(stdout);
    fclose(fp);
    return EXIT_SUCCESS;
    }

    int err = errno;

    if (ferror(fp))
    {
    fprintf(stderr,
    "Error encountered while reading input"
    " from file\n%s\n",
    strerror(err));
    fclose(fp);

    return EXIT_FAILURE;
    }

    fclose(fp);

    return EXIT_SUCCESS;
    }

    In this program I open a file 'data.txt' in 'write' mode.
    Subsequently, I write something into this file. Then I read
    from this file using 'fscanf'. This operation should fail.
    But when I test the error indicator for the stream by
    calling 'ferror(fp)', the statements inside the
    if (ferror(fp))
    {
    }
    are NOT executed.
    Does this mean that error inidcator for the stream is not set
    by 'fscanf' ? Isn't the operation 'reading from a file
    opened in "write" mode' an error ?

    I am unable to understand this.

    Kindly explain.

    Thanks
    V.Subramanian
     
    V.Subramanian, India, Oct 30, 2011
    #1
    1. Advertising

  2. I forgot to add to the OP that I compiled this program under RedHat
    Linux with gcc 3.4.3 as
    gcc -std=c99 -pedantic -Wall -Wextra sample.c

    There is no warning or error.
     
    V.Subramanian, India, Oct 30, 2011
    #2
    1. Advertising

  3. V.Subramanian, India

    Ian Collins Guest

    On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    > This question is for learning purpose only.
    >
    > Consider the program sample.c :
    >
    > #include<stdlib.h>
    > #include<stdio.h>
    > #include<errno.h>
    > #include<string.h>
    >
    > int main()
    > {
    > errno = 0;
    >
    > FILE *fp = fopen("data.txt", "w");
    >
    > if (fp == NULL)
    > {
    > fprintf(stderr,
    > "Could not open input file - data.txt\n%s\n",
    > strerror(errno));
    >
    > return EXIT_FAILURE;
    > }
    >
    > if (fprintf(fp, "test data")< 1)
    > {
    > fprintf(stderr,
    > "could not write message into data.txt\n");
    >
    > return EXIT_FAILURE;
    > }
    >
    > fflush(fp);
    >
    > int a;
    > int b;
    >
    > errno = 0;
    >
    > // I deliberately try to read from the file
    > // opened in 'write' mode
    > if (fscanf(fp, "%d%d",&a,&b) == 2)


    You don't test the return of fscanf. Do so and see what happens.

    > {
    > fprintf(stdout,
    > "a = %d, b= %d\n",
    > a,
    > b);
    > fflush(stdout);
    > fclose(fp);
    > return EXIT_SUCCESS;
    > }
    >
    > int err = errno;
    >
    > if (ferror(fp))
    > {
    > fprintf(stderr,
    > "Error encountered while reading input"
    > " from file\n%s\n",
    > strerror(err));
    > fclose(fp);
    >
    > return EXIT_FAILURE;
    > }
    >
    > fclose(fp);
    >
    > return EXIT_SUCCESS;
    > }
    >
    > In this program I open a file 'data.txt' in 'write' mode.
    > Subsequently, I write something into this file. Then I read
    > from this file using 'fscanf'. This operation should fail.


    But to fail to check!

    > But when I test the error indicator for the stream by
    > calling 'ferror(fp)', the statements inside the
    > if (ferror(fp))
    > {
    > }
    > are NOT executed.
    > Does this mean that error inidcator for the stream is not set
    > by 'fscanf' ? Isn't the operation 'reading from a file
    > opened in "write" mode' an error ?


    No, because the FILE* argument isn't a valid input stream. There's
    nothing wrong with the stream, you are just using it wrong.

    > I am unable to understand this.


    Try opening the stream "r+" and then you will see an error condition
    occur on the stream.

    --
    Ian Collins
     
    Ian Collins, Oct 30, 2011
    #3
  4. V.Subramanian, India

    Ike Naar Guest

    On 2011-10-30, Ian Collins <> wrote:
    > On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >> if (fscanf(fp, "%d%d",&a,&b) == 2)

    >
    > You don't test the return of fscanf. Do so and see what happens.


    He does; he compares the return of fscanf with 2.
     
    Ike Naar, Oct 30, 2011
    #4
  5. V.Subramanian, India

    Ian Collins Guest

    On 10/30/11 09:18 PM, Ike Naar wrote:
    > On 2011-10-30, Ian Collins<> wrote:
    >> On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >>> if (fscanf(fp, "%d%d",&a,&b) == 2)

    >>
    >> You don't test the return of fscanf. Do so and see what happens.

    >
    > He does; he compares the return of fscanf with 2.


    Yes he does, but he does nothing if the test fails.

    --
    Ian Collins
     
    Ian Collins, Oct 30, 2011
    #5
  6. V.Subramanian, India

    Ike Naar Guest

    On 2011-10-30, V.Subramanian, India <> wrote:
    > // opened in 'write' mode
    > if (fscanf(fp, "%d%d", &a, &b) == 2)
    > {
    > fprintf(stdout,
    > "a = %d, b= %d\n",
    > a,
    > b);
    > fflush(stdout);
    > fclose(fp);
    > return EXIT_SUCCESS;
    > }
    >
    > [snip]
    >
    > In this program I open a file 'data.txt' in 'write' mode.
    > Subsequently, I write something into this file. Then I read
    > from this file using 'fscanf'. This operation should fail.


    fscanf does fail (this can be detected by observing that it returns -1).
    But fscanf does not read anything from fp (it isn't allowed to
    because fp is not in 'read' mode), nothing happens to
    the state of fp.

    > But when I test the error indicator for the stream by
    > calling 'ferror(fp)', the statements inside the
    > if (ferror(fp))
    > {
    > }
    > are NOT executed.
    > Does this mean that error inidcator for the stream is not set
    > by 'fscanf' ? Isn't the operation 'reading from a file
    > opened in "write" mode' an error ?


    The operation never happes, the stream is not touched.
     
    Ike Naar, Oct 30, 2011
    #6
  7. V.Subramanian, India

    Eric Sosman Guest

    On 10/30/2011 4:23 AM, Ian Collins wrote:
    > On 10/30/11 09:18 PM, Ike Naar wrote:
    >> On 2011-10-30, Ian Collins<> wrote:
    >>> On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >>>> if (fscanf(fp, "%d%d",&a,&b) == 2)
    >>>
    >>> You don't test the return of fscanf. Do so and see what happens.

    >>
    >> He does; he compares the return of fscanf with 2.

    >
    > Yes he does, but he does nothing if the test fails.


    Perhaps your newsreader has lopped off part of the O.P.'s code.
    In the version I see, the "equals two" case goes down one path and
    the "else" does something entirely different. Lightly edited:

    > if (fscanf(fp, "%d%d", &a, &b) == 2) {
    > fprintf(stdout, "a = %d, b= %d\n", a, b);
    > fflush(stdout);
    > fclose(fp);
    > return EXIT_SUCCESS;
    > }
    > int err = errno;
    > if (ferror(fp)) {
    > fprintf(stderr, "Error encountered while reading input"
    > " from file\n%s\n", strerror(err));
    > fclose(fp);
    > return EXIT_FAILURE;
    > }
    > fclose(fp);
    > return EXIT_SUCCESS;


    --
    Eric Sosman
    d
     
    Eric Sosman, Oct 30, 2011
    #7
  8. V.Subramanian, India

    Ian Collins Guest

    On 10/31/11 01:11 AM, Eric Sosman wrote:
    > On 10/30/2011 4:23 AM, Ian Collins wrote:
    >> On 10/30/11 09:18 PM, Ike Naar wrote:
    >>> On 2011-10-30, Ian Collins<> wrote:
    >>>> On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >>>>> if (fscanf(fp, "%d%d",&a,&b) == 2)
    >>>>
    >>>> You don't test the return of fscanf. Do so and see what happens.
    >>>
    >>> He does; he compares the return of fscanf with 2.

    >>
    >> Yes he does, but he does nothing if the test fails.

    >
    > Perhaps your newsreader has lopped off part of the O.P.'s code.
    > In the version I see, the "equals two" case goes down one path and
    > the "else" does something entirely different. Lightly edited:


    Entirely different in the sense that it doesn't check why fscanf failed.

    > > if (fscanf(fp, "%d%d",&a,&b) == 2) {
    > > fprintf(stdout, "a = %d, b= %d\n", a, b);
    > > fflush(stdout);
    > > fclose(fp);
    > > return EXIT_SUCCESS;
    > > }
    > > int err = errno;
    > > if (ferror(fp)) {
    > > fprintf(stderr, "Error encountered while reading input"
    > > " from file\n%s\n", strerror(err));
    > > fclose(fp);
    > > return EXIT_FAILURE;
    > > }
    > > fclose(fp);
    > > return EXIT_SUCCESS;

    >



    --
    Ian Collins
     
    Ian Collins, Oct 30, 2011
    #8
  9. Ian Collins <> writes:

    > On 10/31/11 01:11 AM, Eric Sosman wrote:
    >> On 10/30/2011 4:23 AM, Ian Collins wrote:
    >>> On 10/30/11 09:18 PM, Ike Naar wrote:
    >>>> On 2011-10-30, Ian Collins<> wrote:
    >>>>> On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >>>>>> if (fscanf(fp, "%d%d",&a,&b) == 2)
    >>>>>
    >>>>> You don't test the return of fscanf. Do so and see what happens.
    >>>>
    >>>> He does; he compares the return of fscanf with 2.
    >>>
    >>> Yes he does, but he does nothing if the test fails.

    >>
    >> Perhaps your newsreader has lopped off part of the O.P.'s code.
    >> In the version I see, the "equals two" case goes down one path and
    >> the "else" does something entirely different. Lightly edited:

    >
    > Entirely different in the sense that it doesn't check why fscanf
    > failed.


    I think it does -- at least it tries to. The code fails because fp is
    an output stream, and all tests to see why fscanf failed will be useless
    on an output stream. The pattern used, though, is reasonable: test for
    success (that fscanf reads the number of items required) and then test
    for errors on the stream and for EOF.

    The only thing that could be added would be to save the return value and
    report how many items matched or failed to match. I tend to do this
    because it simplifies the EOF test, but that is a small matter of style.

    >> > if (fscanf(fp, "%d%d",&a,&b) == 2) {
    >> > fprintf(stdout, "a = %d, b= %d\n", a, b);
    >> > fflush(stdout);
    >> > fclose(fp);
    >> > return EXIT_SUCCESS;
    >> > }
    >> > int err = errno;
    >> > if (ferror(fp)) {
    >> > fprintf(stderr, "Error encountered while reading input"
    >> > " from file\n%s\n", strerror(err));
    >> > fclose(fp);
    >> > return EXIT_FAILURE;
    >> > }
    >> > fclose(fp);


    It might short-circuit the discussion if you say what it is you think
    the OP should be testing for.

    >> > return EXIT_SUCCESS;


    --
    Ben.
     
    Ben Bacarisse, Oct 30, 2011
    #9
  10. V.Subramanian, India

    Ian Collins Guest

    On 10/31/11 08:40 AM, Ben Bacarisse wrote:
    > Ian Collins<> writes:
    >
    >> On 10/31/11 01:11 AM, Eric Sosman wrote:
    >>> On 10/30/2011 4:23 AM, Ian Collins wrote:
    >>>> On 10/30/11 09:18 PM, Ike Naar wrote:
    >>>>> On 2011-10-30, Ian Collins<> wrote:
    >>>>>> On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >>>>>>> if (fscanf(fp, "%d%d",&a,&b) == 2)
    >>>>>>
    >>>>>> You don't test the return of fscanf. Do so and see what happens.
    >>>>>
    >>>>> He does; he compares the return of fscanf with 2.
    >>>>
    >>>> Yes he does, but he does nothing if the test fails.
    >>>
    >>> Perhaps your newsreader has lopped off part of the O.P.'s code.
    >>> In the version I see, the "equals two" case goes down one path and
    >>> the "else" does something entirely different. Lightly edited:

    >>
    >> Entirely different in the sense that it doesn't check why fscanf
    >> failed.

    >
    > I think it does -- at least it tries to. The code fails because fp is
    > an output stream, and all tests to see why fscanf failed will be useless
    > on an output stream. The pattern used, though, is reasonable: test for
    > success (that fscanf reads the number of items required) and then test
    > for errors on the stream and for EOF.
    >
    > The only thing that could be added would be to save the return value and
    > report how many items matched or failed to match. I tend to do this
    > because it simplifies the EOF test, but that is a small matter of style.


    I guess I'm used to the POSIX behaviour where fscanf will set errno on
    failure. In this case, EOF will be returned and errno will be set to
    EBADF to indicate the file has not been opened for reading.

    --
    Ian Collins
     
    Ian Collins, Oct 30, 2011
    #10
  11. V.Subramanian, India

    Carlo Dapor Guest

    On Oct 30, 7:59 am, "V.Subramanian, India"
    <> wrote:
    > This question is for learning purpose only.
    >
    > Consider the program sample.c :
    >
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <errno.h>
    > #include <string.h>
    >
    > int main()
    > {
    >         errno = 0;
    >
    >         FILE *fp = fopen("data.txt", "w");
    >
    >         if (fp == NULL)
    >         {
    >                 fprintf(stderr,
    >                         "Could not open input file - data.txt\n%s\n",
    >                         strerror(errno));
    >
    >                 return EXIT_FAILURE;
    >         }
    >
    >         if (fprintf(fp, "test data") < 1)
    >         {
    >                 fprintf(stderr,
    >                         "could not write message into data.txt\n");
    >
    >                 return EXIT_FAILURE;
    >         }
    >
    >         fflush(fp);
    >
    >         int a;
    >         int b;
    >
    >         errno = 0;
    >
    >         // I deliberately try to read from the file
    >         // opened in 'write' mode
    >         if (fscanf(fp, "%d%d", &a, &b) == 2)
    >         {
    >                 fprintf(stdout,
    >                         "a = %d, b= %d\n",
    >                         a,
    >                         b);
    >                 fflush(stdout);
    >                 fclose(fp);
    >                 return EXIT_SUCCESS;
    >         }
    >
    >         int err = errno;
    >
    >         if (ferror(fp))
    >         {
    >                 fprintf(stderr,
    >                          "Error encountered while reading input"
    >                          " from file\n%s\n",
    >                          strerror(err));
    >                 fclose(fp);
    >
    >                 return EXIT_FAILURE;
    >         }
    >
    >         fclose(fp);
    >
    >         return EXIT_SUCCESS;
    >
    > }
    >
    > In this program I open a file 'data.txt' in 'write' mode.
    > Subsequently, I write something into this file. Then I read
    > from this file using 'fscanf'. This operation should fail.
    > But when I test the error indicator for the stream by
    > calling 'ferror(fp)', the statements inside the
    >         if (ferror(fp))
    >         {
    >          }
    > are NOT executed.
    > Does this mean that error inidcator for the stream is not set
    > by 'fscanf' ? Isn't the operation 'reading from a file
    > opened in "write" mode' an error ?
    >
    > I am unable to understand this.
    >
    > Kindly explain.
    >
    > Thanks
    > V.Subramanian


    Hello V. Subramanian


    I also learned a few things, thanks to your posting.
    The results are from Mac OS X 10.6.8, they may not apply to RedHat
    Linux.

    Allow me to point out some observations.

    1. fscanf's behaviour

    What I take away is that fscanf(3) does not set errno, whether the
    call succeeds or not.
    Modifying your original source code, errno is always -234 below.
    Calling ferror(fp) after fscanf has no effect.

    2. Format used

    You assumed that two numbers are adjacent ("%d%d").
    This is rather misleading.
    Say the input were 193.
    Should that be read as "1" followed by "93" (case 1), or "19" followed
    by "3" (case 2).
    The solution is to specify "%1d%2d" for case 1 and "%2d%1d" for case
    2.
    Another solution is to separate the numbers with a white-space, like
    below.

    3. Writing and reading to/from the same file

    As pointed out, you must create the file with "r+" or "w+".

    4. File position

    After writing to the file, you are at the end of the file.
    If you want to read from it, you must re-position the reader to the
    beginning, with fseek or rewind.
    Or you could call fclose(fp) followed by fopen(...).

    Here's the code:


    #include <stdlib.h>
    #include <stdio.h>
    #include <errno.h>


    int
    main (int argc, char *argv[])
    {
    int a, b, count = -1, status = EXIT_SUCCESS;
    FILE *fp = fopen ("data.txt", "w+");

    fprintf (fp, "23 57"); // valid input
    //fprintf (fp, "no number"); // invalid input

    if (0 != errno) {
    fprintf (stderr, "Could not write data: '%s'\n", strerror
    (errno));

    return EXIT_FAILURE;
    }

    // re-set the position to the beginning
    rewind (fp);

    // unfortunately, errno is not set, whether fscanf succeeds or
    not!
    errno = -234;
    count = fscanf (fp, "%d %d", &a, &b);

    if (2 == count) {
    fprintf (stdout, "a=%d, b=%d, errno=%d\n", a, b, errno);
    }
    else {
    fprintf (stderr, "Expected 2 tokens, got %d; errno=%d\n",
    count, errno);
    status = EXIT_FAILURE;
    }

    fclose (fp);
    return status;
    }


    Regards,
    --
    Carlo
     
    Carlo Dapor, Oct 31, 2011
    #11
  12. V.Subramanian, India

    Ian Collins Guest

    On 10/31/11 03:16 PM, Carlo Dapor wrote:
    >
    > I also learned a few things, thanks to your posting.
    > The results are from Mac OS X 10.6.8, they may not apply to RedHat
    > Linux.
    >
    > Allow me to point out some observations.
    >
    > 1. fscanf's behaviour
    >
    > What I take away is that fscanf(3) does not set errno, whether the
    > call succeeds or not.


    It isn't required to set errno by the C standard, but it is on a POSIX
    compliant system. So it should set errno on both Linux and OSX.

    --
    Ian Collins
     
    Ian Collins, Oct 31, 2011
    #12
  13. On Oct 30, 12:19 pm, Ian Collins <> wrote:
    > On 10/30/11 07:59 PM, V.Subramanian, India wrote:
    >
    >
    >
    > > This question is for learning purpose only.

    >
    > > Consider the program sample.c :

    >
    > > #include<stdlib.h>
    > > #include<stdio.h>
    > > #include<errno.h>
    > > #include<string.h>

    >
    > > int main()
    > > {
    > > errno = 0;

    >
    > > FILE *fp = fopen("data.txt", "w");

    >
    > > if (fp == NULL)
    > > {
    > > fprintf(stderr,
    > > "Could not open input file - data.txt\n%s\n",
    > > strerror(errno));

    >
    > > return EXIT_FAILURE;
    > > }

    >
    > > if (fprintf(fp, "test data")< 1)
    > > {
    > > fprintf(stderr,
    > > "could not write message into data.txt\n");

    >
    > > return EXIT_FAILURE;
    > > }

    >
    > > fflush(fp);

    >
    > > int a;
    > > int b;

    >
    > > errno = 0;

    >
    > > // I deliberately try to read from the file
    > > // opened in 'write' mode
    > > if (fscanf(fp, "%d%d",&a,&b) == 2)

    >
    > You don't test the return of fscanf. Do so and see what happens.
    >
    >
    >
    > > {
    > > fprintf(stdout,
    > > "a = %d, b= %d\n",
    > > a,
    > > b);
    > > fflush(stdout);
    > > fclose(fp);
    > > return EXIT_SUCCESS;
    > > }

    >
    > > int err = errno;

    >
    > > if (ferror(fp))
    > > {
    > > fprintf(stderr,
    > > "Error encountered while reading input"
    > > " from file\n%s\n",
    > > strerror(err));
    > > fclose(fp);

    >
    > > return EXIT_FAILURE;
    > > }

    >
    > > fclose(fp);

    >
    > > return EXIT_SUCCESS;
    > > }

    >
    > > In this program I open a file 'data.txt' in 'write' mode.
    > > Subsequently, I write something into this file. Then I read
    > > from this file using 'fscanf'. This operation should fail.

    >
    > But to fail to check!
    >
    > > But when I test the error indicator for the stream by
    > > calling 'ferror(fp)', the statements inside the
    > > if (ferror(fp))
    > > {
    > > }
    > > are NOT executed.
    > > Does this mean that error inidcator for the stream is not set
    > > by 'fscanf' ? Isn't the operation 'reading from a file
    > > opened in "write" mode' an error ?

    >
    > No, because the FILE* argument isn't a valid input stream. There's
    > nothing wrong with the stream, you are just using it wrong.
    >
    > > I am unable to understand this.

    >
    > Try opening the stream "r+" and then you will see an error condition
    > occur on the stream.
    >
    > --
    > Ian Collins



    Does 'fscanf' set the error indicator of a stream on error while
    reading the stream ? If so, ferror(fp) should succeed and the contents
    inside 'if (ferror(fp)) {...}' should be executed. Kindly provide a
    code for the above scenario. I am unable to come up with this code. I
    tried the following:

    In the original program mentioned in the OP, I just modified the mode
    to "r+" and also "w+" without any other code change; but in both cases
    the ferror(fp) part was not executed.

    I am compiling the program with the following options:
    gcc -std=c99 -pedantic -Wall -Wextra sample.c

    I thought, the above options use Standard C and not POSIX. Is it
    correct ?

    Please help me understand under what circumstances, if at all, fscanf
    sets the error indicator for a stream. If it doesn't, I NEVER have to
    do the check 'if (ferror(fp)) {...}' after a call to fscanf. Am I
    correct ?.

    Thanks
    V.Subramanian
     
    V.Subramanian, India, Oct 31, 2011
    #13
  14. V.Subramanian, India

    Ike Naar Guest

    On 2011-10-31, Carlo Dapor <> wrote:
    > 2. Format used
    >
    > You assumed that two numbers are adjacent ("%d%d").


    No. "%d%d" is a valid format for reading two separated integers;
    it will skip initial whitespace before the first integer, read the
    first integer, skip whitespace beteeen the first and the second
    integer, and read the second integer.

    > This is rather misleading.
    > Say the input were 193.
    > Should that be read as "1" followed by "93" (case 1), or "19" followed
    > by "3" (case 2).


    Neither; it will read the first number as 193 (assuming the next
    character after "193" does not extend that number to a larger valid
    integer). Then any separating whitespace is skipped, and a second
    integer will be read. If there is no second integer in the input
    stream, fscanf will still read the first integer as 193, then return
    1 to indicate that only one item was read.

    > The solution is to specify "%1d%2d" for case 1 and "%2d%1d" for case
    > 2.


    In general you do not know beforehand how large the numbers in the
    input stream will be, so you cannot predict the number of digits
    to read for the first number. Separating the numbers by whitespace
    is often the better way.
     
    Ike Naar, Oct 31, 2011
    #14
  15. V.Subramanian, India

    Alan Curry Guest

    In article <>,
    V.Subramanian, India <> wrote:
    >
    >Does 'fscanf' set the error indicator of a stream on error while
    >reading the stream ? If so, ferror(fp) should succeed and the contents
    >inside 'if (ferror(fp)) {...}' should be executed. Kindly provide a
    >code for the above scenario. I am unable to come up with this code. I
    >tried the following:


    It's nice that you want to test your error handling code path, but injecting
    an error that will be reported by ferror() is not easy. ferror() is the
    indicator of I/O errors, which usually have a cause that exists outside your
    program, like a hard disk with bad sectors.

    Check the return value of fscanf first. If it returned EOF, then you can call
    ferror() to distinguish between a normal end-of-file condition and an I/O
    error. In all other cases, ferror() won't be useful.

    --
    Alan Curry
     
    Alan Curry, Oct 31, 2011
    #15
  16. V.Subramanian, India

    Ian Collins Guest

    On 10/31/11 08:14 PM, Alan Curry wrote:
    > In article<>,
    > V.Subramanian, India<> wrote:
    >>
    >> Does 'fscanf' set the error indicator of a stream on error while
    >> reading the stream ? If so, ferror(fp) should succeed and the contents
    >> inside 'if (ferror(fp)) {...}' should be executed. Kindly provide a
    >> code for the above scenario. I am unable to come up with this code. I
    >> tried the following:

    >
    > It's nice that you want to test your error handling code path, but injecting
    > an error that will be reported by ferror() is not easy. ferror() is the
    > indicator of I/O errors, which usually have a cause that exists outside your
    > program, like a hard disk with bad sectors.
    >
    > Check the return value of fscanf first. If it returned EOF, then you can call
    > ferror() to distinguish between a normal end-of-file condition and an I/O
    > error. In all other cases, ferror() won't be useful.


    It's unfortunate that without the additional POSIX requirement, there
    isn't a standard way to detect the error condition (invalid operation on
    the stream) in the original example. I guess the best option is to call
    feof() on the stream, at least that way you will be able to
    differentiate between an end of file condition and an error.

    --
    Ian Collins
     
    Ian Collins, Oct 31, 2011
    #16
  17. On Oct 31, 5:55 am, "V.Subramanian, India"
    <> wrote:
    > On Oct 30, 12:19 pm, Ian Collins <> wrote:
    > > On 10/30/11 07:59 PM, V.Subramanian, India wrote:


    <snip>

    > > No, because the FILE* argument isn't a valid input stream.  There's
    > > nothing wrong with the stream, you are just using it wrong.

    >
    > > > I am unable to understand this.

    >
    > > Try opening the stream "r+" and then you will see an error condition
    > > occur on the stream.

    >
    > > --
    > > Ian Collins


    it's usual to snip sigs (the bit after a "-- ")

    <snip>

    > I am compiling the program with the following options:
    > gcc -std=c99 -pedantic -Wall -Wextra sample.c
    >
    > I thought, the above options use Standard C and not POSIX. Is it
    > correct ?


    To The Best Of My Knowledge flags to gcc specify the behaviour of gcc
    (ie. of the compiler), whilst fscanf() is part of the library. gcc is
    actually independent of the library and uses whatever is provided by
    the system (there are semi-portable versions of the c library). hence
    on a Posix compliant system you get a Posix compiant C library.

    Note the C standard only specifies which standdard functions /must/
    set errno. It doesn't say that others can't. (pedant point: I'm sure
    there are a few library functions that must not set errno).

    > Please help me understand under what circumstances, if at all, fscanf
    > sets the error indicator for a stream. If it doesn't, I NEVER have to
    > do the check 'if (ferror(fp)) {...}' after a call to fscanf. Am I
    > correct ?.
     
    Nick Keighley, Oct 31, 2011
    #17
  18. (Alan Curry) writes:

    > In article <>,
    > V.Subramanian, India <> wrote:
    >>
    >>Does 'fscanf' set the error indicator of a stream on error while
    >>reading the stream ? If so, ferror(fp) should succeed and the contents
    >>inside 'if (ferror(fp)) {...}' should be executed. Kindly provide a
    >>code for the above scenario. I am unable to come up with this code. I
    >>tried the following:

    >
    > It's nice that you want to test your error handling code path, but injecting
    > an error that will be reported by ferror() is not easy.


    True. I do it with freopen sometimes in conjunction with fwide. It's
    not at all portable, but where it works it's great to be able cause IO
    fails at any desired test point.

    To break an input stream, re-open it with mode "w", and vice-versa. If
    the stream is read-write, re-open it read-write but set the stream to be
    wide oriented (or byte oriented if you are really using wide stream).

    <snip>
    --
    Ben.
     
    Ben Bacarisse, Oct 31, 2011
    #18
  19. Nick Keighley <> writes:
    [...]
    > Note the C standard only specifies which standdard functions /must/
    > set errno. It doesn't say that others can't. (pedant point: I'm sure
    > there are a few library functions that must not set errno).

    [...]

    Actually, I don't think there are any.

    C99 7.5p3:

    The value of errno is zero at program startup, but is never set
    to zero by any library function. The value of errno may be set
    to nonzero by a library function call whether or not there is
    an error, provided the use of errno is not documented in the
    description of the function in this International Standard.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Oct 31, 2011
    #19
    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. Chris Torek
    Replies:
    0
    Views:
    398
    Chris Torek
    Jul 14, 2003
  2. David Rubin
    Replies:
    0
    Views:
    447
    David Rubin
    Jul 14, 2003
  3. Benedicte

    Problems when reading from a file with fscanf

    Benedicte, Feb 4, 2004, in forum: C Programming
    Replies:
    3
    Views:
    452
    Al Bowers
    Feb 4, 2004
  4. fscanf reading lines

    , Mar 8, 2006, in forum: C Programming
    Replies:
    7
    Views:
    878
    Fred Kleinschmidt
    Mar 8, 2006
  5. John
    Replies:
    4
    Views:
    641
    Keith Thompson
    Sep 27, 2006
Loading...

Share This Page