File Read help reqd

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Naren

    #1

    File Read help reqd

    Hello All,

    Can any one help me in this file read problem.

    #include <stdio.h>



    int main()
    {
    FILE* fp = fopen("TITLE.mx 2","rb");

    char h[100];

    while(fscanf(fp ,"%[^\r\n]",h) != EOF)
    {
    fprintf(stdout, "%s",h);
    if((fscanf(fp," %[\r\n]",h) == EOF)) //dummy
    break;
    }


    fclose(fp);
    return 0;

    }

    it goes into an infinite loop.

    Am i eating up the EOF?

    here while(fscanf(fp ,"%[^\r\n]",h) != EOF)?

    how to avoid it?

    Thanks in advance.

    Regards,
    Naren.

  • CBFalconer

    #2
    Re: File Read help reqd

    Naren wrote:[color=blue]
    >
    > #include <stdio.h>
    > int main()
    > {
    > FILE* fp = fopen("TITLE.mx 2","rb");
    > char h[100];
    >
    > while(fscanf(fp ,"%[^\r\n]",h) != EOF)[/color]

    fscanf can never return EOF. Try reading its definition.

    --
    "I conclude that there are two ways of constructing a software
    design: One way is to make it so simple that there are obviously
    no deficiencies and the other way is to make it so complicated
    that there are no obvious deficiencies." -- C. A. R. Hoare


    Comment

    • Robert Gamble

      #3
      Re: File Read help reqd

      CBFalconer wrote:[color=blue]
      > Naren wrote:[color=green]
      > >
      > > #include <stdio.h>
      > > int main()
      > > {
      > > FILE* fp = fopen("TITLE.mx 2","rb");
      > > char h[100];
      > >
      > > while(fscanf(fp ,"%[^\r\n]",h) != EOF)[/color]
      >
      > fscanf can never return EOF. Try reading its definition.[/color]

      According to my copy of the Standard:
      7.19.6.2p16:

      The fscanf function returns the value of the macro EOF if an input
      failure occurs
      before any conversion.

      Am I missing something?

      Robert Gamble

      Comment

      • Chris Torek

        #4
        Re: File Read help reqd

        In article <1117631262.470 902.317830@g47g 2000cwa.googleg roups.com>
        Naren <narendranath.t hadkal@gmail.co m> wrote:
        [snippage, and minor vertical compression][color=blue]
        > FILE* fp = fopen("TITLE.mx 2","rb");
        > char h[100];
        >
        > while(fscanf(fp ,"%[^\r\n]",h) != EOF) {
        > fprintf(stdout, "%s",h);
        > if((fscanf(fp," %[\r\n]",h) == EOF)) //dummy
        > break;
        > }
        >... goes into an infinite loop.[/color]

        One possibility is that the fopen() has failed and fp==NULL and
        the undefined behavior of calling fscanf() with this NULL is
        that it does nothing other than return a value not equal to -1.
        For instance, perhaps your fscanf() happens to return 42 when
        called with NULL (and read no data, or at least do nothing
        visibly harmful). This could easily result in an infinite
        loop.

        Another possibility is that one of the fscanf() calls overruns the
        buffer h[], i.e., there are more than 99 non-\r non-\n characters
        in sequence at some point, or there are more than 99 \r-or-\n
        characters in sequence at some other point. This would store
        more than 100 "char"s in the 100-char array, leading to undefined
        behavior, which could also result in an infinite loop.

        It also seems very odd to open with "rb" and then use fgets(),
        since fgets() is a "text-file-oriented" operation (text files are
        composed of "lines", while binary files contain arbitrary binary
        data not necessarily composed of lines). But this in and of
        itself should not result in an infinite loop.

        Other than these issues, the code *should* not loop forever. The
        first fscanf() directive -- a "%[" -- matches one or more non-\r
        non-\n characters, or fails with either an input or a matching
        failure. In most cases (non-blank first text line), it will succeed,
        and read-and-convert the non-\r-or-\n characters, storing them in
        h[].

        If the file begins with a sequence of \r-or-\n characters, the
        first fscanf() performed will fail with a matching failure and
        return 0, leaving garbage in the array h[]. The fprintf() to stdout
        would then technically have undefined behavior, which theoretically
        could result in an infinite loop; but in practical terms, on the
        computer you are using (the one I see in my crystal ball :-) ),
        you would just get either garbage output, or no output at all, from
        that fprintf().

        Having either succeeded or failed with a matching failure, fscanf()
        will then return either 1 or 0 (respectively). You ignore this
        distinction in return values -- which is almost always a bug, and
        is indeed a bug in this case -- and go on to print the contents of
        the array (possibly garbage).

        You then call fscanf() again, using another %[ directive, but this
        one says "read and convert at least one, and as many as possible,
        \r or \n characters". Since the previous conversion will have read
        and converted everything that is not a \r or \n, the only possible
        character in the stream at this point is \r or \n. Thus, if there
        are any characters to read at all, the %[ directive will definitely
        succeed. The only other possibility is that getc(fp) will return
        EOF (due to input error or end-of-file), rather than returning a
        '\r' or '\n' character; in that case, the fscanf() call itself will
        return EOF, and the "break" will terminate the loop. Since the
        loop does not terminate, we can assume that fscanf() does find at
        least one \r or \n, and writes them into the array h[]. (Thus, if
        there are 37 '\r' characters followed by 3 '\n's followed by 9
        '\r's followed by 'x' or EOF, h[] will have 37+3+9+1 = 50 bytes
        written into it.) The fscanf() call will then return 1 -- the
        only possible return values are EOF and 1, in this case. Hence
        the test fscanf(...)==EO F is sufficient, unlike the initial one in
        the while loop.

        If the fscanf() does return 1, we know that the fscanf() stopped
        at either a non-\r non-\n character, or it encountered EOF. Thus,
        subsequent trips through the while loop's test will have a return
        value from fscanf() of either EOF or 1. Only the very first
        fscanf() performed can return 0 (when the file begins with a
        '\r' or '\n' character).

        All of this may leave the original poster with the question of what
        he *should* code, instead of the above; but no one can really answer
        that, as he has not expressed a goal, merely a question about the
        loop. I can make a guess here (that the goal is to remove all
        '\n' and/or '\r' characters from a binary file), but it is just a
        guess, and it seems a little unlikely.
        --
        In-Real-Life: Chris Torek, Wind River Systems
        Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
        email: forget about it http://web.torek.net/torek/index.html
        Reading email is like searching for food in the garbage, thanks to spammers.

        Comment

        • CBFalconer

          #5
          Re: File Read help reqd

          Robert Gamble wrote:[color=blue]
          > CBFalconer wrote:
          >[/color]
          .... snip ...[color=blue]
          >[color=green]
          >> fscanf can never return EOF. Try reading its definition.[/color]
          >
          > According to my copy of the Standard:
          > 7.19.6.2p16:
          >
          > The fscanf function returns the value of the macro EOF if an input
          > failure occurs before any conversion.
          >
          > Am I missing something?[/color]

          No, but I am. Thanks for the correction.

          --
          "I conclude that there are two ways of constructing a software
          design: One way is to make it so simple that there are obviously
          no deficiencies and the other way is to make it so complicated
          that there are no obvious deficiencies." -- C. A. R. Hoare

          Comment

          • Alberto Giménez

            #6
            Re: File Read help reqd

            El Thu, 02 Jun 2005 10:19:36 GMT, CBFalconer escribió:[color=blue][color=green]
            >> According to my copy of the Standard:
            >> 7.19.6.2p16:
            >>
            >> The fscanf function returns the value of the macro EOF if an input
            >> failure occurs before any conversion.
            >>
            >> Am I missing something?[/color]
            >
            > No, but I am. Thanks for the correction.[/color]

            Not at all. It says *input failure* needed to return EOF. So, if a conversion
            occurs ([^\r\n]) with no input failure, fscanf will not return EOF and
            thus the while will be a forever loop. Please correct me if i'm wrong.

            Greetings
            --
            Luis Alberto Giménez
            JabberID: SimManiac@bulma lug.net
            GnuPG ID: 0x3BAABDE1

            Comment

            • Walter Roberson

              #7
              Re: File Read help reqd

              In article <m5kn7d.9a.ln@1 27.0.0.1>,
              Alberto =?iso-8859-1?Q?Gim=E9nez?= <algibe@telelin e.es> wrote:[color=blue]
              >El Thu, 02 Jun 2005 10:19:36 GMT, CBFalconer escribió:[color=green][color=darkred]
              >>> According to my copy of the Standard:
              >>> 7.19.6.2p16:[/color][/color][/color]
              [color=blue][color=green][color=darkred]
              >>> The fscanf function returns the value of the macro EOF if an input
              >>> failure occurs before any conversion.[/color][/color][/color]
              [color=blue]
              >Not at all. It says *input failure* needed to return EOF. So, if a conversion
              >occurs ([^\r\n]) with no input failure, fscanf will not return EOF and
              >thus the while will be a forever loop. Please correct me if i'm wrong.[/color]

              No, if a conversion occurs then at least one character will be removed
              from the input stream -- and with that particular format, all the
              characters until EOF or the first \r or \n will be removed from the
              input stream.

              Thus after the execution of the fscanf() that is the condition of the
              while() loop, if a conversion occured then input has been removed and
              one is positioned at an EOF or \r or \n. Then one encounters the
              second fscanf() which is the condition of the "if" statement.

              If one was at a \r or \n then the fscanf() at the "if" will remove all
              the \r and \n that await in sequence, either leaving one at EOF or
              at a character which is not \r or \n and looping back.

              Inductively, this will repeat until one or the other of the fscanf()
              encounters EOF; at that point, the next fscanf() *will* return EOF
              and either the 'break' will take effect or the while() condition will
              become false and the loop will end.


              There is the case where the input starts out positioned at \r or \n
              but there are characters there. In that situation, the conversion count
              will be 0 for the while()'s fscanf(), but 0 != EOF so the loop body
              will be executed and the inner fscanf() will consume the \r \n sequence
              leading back to the case solved above.


              The next bit you need to know for this to work is that fscanf()
              *defines* that when EOF is reached with no conversion having taken
              place, that an "input failure" is returned. And then, as was quoted,
              that "input failure" is signaled by the value EOF being returned.

              For more certainty, examine the example at the end of the C89
              description of fscanf(), and notice that it -specifically- has
              "count" becoming EOF at the end of the input stream.

              --
              Ceci, ce n'est pas une idée.

              Comment

              • Naren

                #8
                Re: File Read help reqd

                Hello All,

                I am extremely sorry for the delay,
                Thanks for answers.

                I have thing to add if i just added

                while(!feof(fp) && fscanf(fp,"%[^\r\n]",h) != EOF)

                It breaks the infinte loop and it works fine. Is there anything wrong
                in my usage?

                Thanks and Regards,
                Naren.

                Comment

                Working...