Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #12274 > unrolled thread

no error by fscanf on reading from output file

Started by"V.Subramanian, India" <subramanian100in@yahoo.com>
First post2011-10-29 23:59 -0700
Last post2011-10-31 07:02 +0000
Articles 19 — 9 participants

Back to article view | Back to comp.lang.c


Contents

  no error by fscanf on reading from output file "V.Subramanian, India" <subramanian100in@yahoo.com> - 2011-10-29 23:59 -0700
    Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-30 20:19 +1300
      Re: no error by fscanf on reading from output file Ike Naar <ike@iceland.freeshell.org> - 2011-10-30 08:18 +0000
        Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-30 21:23 +1300
          Re: no error by fscanf on reading from output file Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-10-30 08:11 -0400
            Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-31 07:38 +1300
              Re: no error by fscanf on reading from output file Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-30 19:40 +0000
                Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-31 08:50 +1300
    Re: no error by fscanf on reading from output file "V.Subramanian, India" <subramanian100in@yahoo.com> - 2011-10-30 00:01 -0700
    Re: no error by fscanf on reading from output file Ike Naar <ike@iceland.freeshell.org> - 2011-10-30 08:39 +0000
    Re: no error by fscanf on reading from output file Carlo Dapor <catull@gmail.com> - 2011-10-30 19:16 -0700
      Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-31 15:50 +1300
        Re: no error by fscanf on reading from output file "V.Subramanian, India" <subramanian100in@yahoo.com> - 2011-10-30 22:55 -0700
          Re: no error by fscanf on reading from output file pacman@kosh.dhis.org (Alan Curry) - 2011-10-31 07:14 +0000
            Re: no error by fscanf on reading from output file Ian Collins <ian-news@hotmail.com> - 2011-10-31 20:56 +1300
            Re: no error by fscanf on reading from output file Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-31 15:43 +0000
          Re: no error by fscanf on reading from output file Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-10-31 01:35 -0700
            Re: no error by fscanf on reading from output file Keith Thompson <kst-u@mib.org> - 2011-10-31 13:46 -0700
      Re: no error by fscanf on reading from output file Ike Naar <ike@iceland.freeshell.org> - 2011-10-31 07:02 +0000

#12274 — no error by fscanf on reading from output file

From"V.Subramanian, India" <subramanian100in@yahoo.com>
Date2011-10-29 23:59 -0700
Subjectno error by fscanf on reading from output file
Message-ID<9b198cc9-d374-4a14-a100-91b74eb12d9e@a12g2000prb.googlegroups.com>
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

[toc] | [next] | [standalone]


#12275

FromIan Collins <ian-news@hotmail.com>
Date2011-10-30 20:19 +1300
Message-ID<9h4c3fFgamU1@mid.individual.net>
In reply to#12274
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

[toc] | [prev] | [next] | [standalone]


#12279

FromIke Naar <ike@iceland.freeshell.org>
Date2011-10-30 08:18 +0000
Message-ID<slrn3vfsjaq22a.9k6.ike@iceland.freeshell.org>
In reply to#12275
On 2011-10-30, Ian Collins <ian-news@hotmail.com> 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.

[toc] | [prev] | [next] | [standalone]


#12281

FromIan Collins <ian-news@hotmail.com>
Date2011-10-30 21:23 +1300
Message-ID<9h4frvFgamU3@mid.individual.net>
In reply to#12279
On 10/30/11 09:18 PM, Ike Naar wrote:
> On 2011-10-30, Ian Collins<ian-news@hotmail.com>  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

[toc] | [prev] | [next] | [standalone]


#12285

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-10-30 08:11 -0400
Message-ID<j8jeto$sue$1@dont-email.me>
In reply to#12281
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<ian-news@hotmail.com> 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
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#12302

FromIan Collins <ian-news@hotmail.com>
Date2011-10-31 07:38 +1300
Message-ID<9h5jsbFgakU1@mid.individual.net>
In reply to#12285
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<ian-news@hotmail.com>  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

[toc] | [prev] | [next] | [standalone]


#12307

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-10-30 19:40 +0000
Message-ID<0.b91d766b6392bf3ae1cf.20111030194003GMT.87hb2qfeuk.fsf@bsb.me.uk>
In reply to#12302
Ian Collins <ian-news@hotmail.com> 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<ian-news@hotmail.com>  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.

[toc] | [prev] | [next] | [standalone]


#12309

FromIan Collins <ian-news@hotmail.com>
Date2011-10-31 08:50 +1300
Message-ID<9h5o4pFgakU3@mid.individual.net>
In reply to#12307
On 10/31/11 08:40 AM, Ben Bacarisse wrote:
> Ian Collins<ian-news@hotmail.com>  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<ian-news@hotmail.com>   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

[toc] | [prev] | [next] | [standalone]


#12276

From"V.Subramanian, India" <subramanian100in@yahoo.com>
Date2011-10-30 00:01 -0700
Message-ID<a41ef539-91bc-426d-8b61-c9472f5cfaef@a12g2000prb.googlegroups.com>
In reply to#12274
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.

[toc] | [prev] | [next] | [standalone]


#12282

FromIke Naar <ike@iceland.freeshell.org>
Date2011-10-30 08:39 +0000
Message-ID<slrn3vfsjaq39d.9k6.ike@iceland.freeshell.org>
In reply to#12274
On 2011-10-30, V.Subramanian, India <subramanian100in@yahoo.com> 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.

[toc] | [prev] | [next] | [standalone]


#12311

FromCarlo Dapor <catull@gmail.com>
Date2011-10-30 19:16 -0700
Message-ID<88a48804-4b47-41f8-bd12-e5b8b4c7df85@m19g2000vbm.googlegroups.com>
In reply to#12274
On Oct 30, 7:59 am, "V.Subramanian, India"
<subramanian10...@yahoo.com> 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

[toc] | [prev] | [next] | [standalone]


#12313

FromIan Collins <ian-news@hotmail.com>
Date2011-10-31 15:50 +1300
Message-ID<9h6go1FcetU1@mid.individual.net>
In reply to#12311
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

[toc] | [prev] | [next] | [standalone]


#12317

From"V.Subramanian, India" <subramanian100in@yahoo.com>
Date2011-10-30 22:55 -0700
Message-ID<721e72aa-54ae-4a90-997f-960266c961ff@u37g2000prh.googlegroups.com>
In reply to#12313
On Oct 30, 12:19 pm, Ian Collins <ian-n...@hotmail.com> 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

[toc] | [prev] | [next] | [standalone]


#12321

Frompacman@kosh.dhis.org (Alan Curry)
Date2011-10-31 07:14 +0000
Message-ID<j8lhsg$uis$1@speranza.aioe.org>
In reply to#12317
In article <721e72aa-54ae-4a90-997f-960266c961ff@u37g2000prh.googlegroups.com>,
V.Subramanian, India <subramanian100in@yahoo.com> 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

[toc] | [prev] | [next] | [standalone]


#12322

FromIan Collins <ian-news@hotmail.com>
Date2011-10-31 20:56 +1300
Message-ID<9h72kkF67vU1@mid.individual.net>
In reply to#12321
On 10/31/11 08:14 PM, Alan Curry wrote:
> In article<721e72aa-54ae-4a90-997f-960266c961ff@u37g2000prh.googlegroups.com>,
> V.Subramanian, India<subramanian100in@yahoo.com>  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

[toc] | [prev] | [next] | [standalone]


#12358

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-10-31 15:43 +0000
Message-ID<0.989a64b7a7a5a74310a9.20111031154349GMT.878vo1dv4a.fsf@bsb.me.uk>
In reply to#12321
pacman@kosh.dhis.org (Alan Curry) writes:

> In article <721e72aa-54ae-4a90-997f-960266c961ff@u37g2000prh.googlegroups.com>,
> V.Subramanian, India <subramanian100in@yahoo.com> 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.

[toc] | [prev] | [next] | [standalone]


#12325

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2011-10-31 01:35 -0700
Message-ID<f01b76a8-1726-4c8a-a7e7-bee91d6e77d9@p16g2000yqd.googlegroups.com>
In reply to#12317
On Oct 31, 5:55 am, "V.Subramanian, India"
<subramanian10...@yahoo.com> wrote:
> On Oct 30, 12:19 pm, Ian Collins <ian-n...@hotmail.com> 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 ?.

[toc] | [prev] | [next] | [standalone]


#12404

FromKeith Thompson <kst-u@mib.org>
Date2011-10-31 13:46 -0700
Message-ID<ln39e8khyg.fsf@nuthaus.mib.org>
In reply to#12325
Nick Keighley <nick_keighley_nospam@hotmail.com> 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) kst-u@mib.org  <http://www.ghoti.net/~kst>
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#12320

FromIke Naar <ike@iceland.freeshell.org>
Date2011-10-31 07:02 +0000
Message-ID<slrn3vfsjasi0u.447.ike@iceland.freeshell.org>
In reply to#12311
On 2011-10-31, Carlo Dapor <catull@gmail.com> 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.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web