fgets() replacement

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Paul D. Boyle

    #16
    Re: fgets() replacement

    Eric Sosman <Eric.Sosman@su n.com> wrote:
    : Paul D. Boyle wrote:
    :> There was a recent thread in this group which talked about the
    :> shortcomings of fgets(). I decided to try my hand at writing a

    : First criticism: The function does too much. This is, of
    : course, a matter of taste, but if the goal is "a replacement
    : for fgets()" I think the validate() business is extraneous.
    : (Even the `sz' parameter raises my eyebrows a little, albeit
    : not a lot.)

    : IMHO, a low-level library function should do one thing,
    : do it well, and do it in a manner that facilitates combining
    : it with other functions to create grander structures. Or as
    : my old fencing coach used to admonish me when I got overenthused
    : with tricky multiple-feint combinations: "Keep It Simple, Stupid."

    I appreciate your criticisms. I especially agree that the 'int
    (*validate)(int )' validation is, at best, misplaced to be used by this
    low level function. I do like, however, the idea of having some
    way of validating the input which can be simply plugged in without
    messing with the main flow of the program.

    : far towards the baroque. In effect, USER_DIALOG_H and the
    : associated macros become part of the function's specification.
    : That specification now encompasses one return value encoding
    : three distinguishable states, four function arguments (two
    : with usage rules not expressible to the compiler), and five
    : macros. That strikes me as *way* too much for "a replacement
    : for fgets()."

    When I was writing the function my idea changed from returning
    a size_t of the number of bytes read to an error code based
    returned. I agree that this was muddled by "changing horses
    in mid stream.


    : ("All right, Smarty Pants, how would *you* do it?")

    : Fair enough. Everybody, it seems, writes an fgets()
    : replacement eventually, and here's the .h text for mine:

    : char *getline(FILE *stream);

    I did write another function with this prototype. Based on
    how I will combine this with other input taking and parsing
    functions, I am thinking of some thing like:

    char *get_line( FILE *in, size_t *sz );

    /* where 'sz' will "return" the number of bytes written */


    or
    size_t get_line( FILE *in, char **line );

    I haven't decided yet which one to go with though.


    :> #define ERROR_MEMORY (-1)
    :> #define ERROR_ILLEGAL_C HAR (-2)

    : Pointless parentheses.

    I feel embarrassed. Shame is a good teacher. :-)

    Again, thank-you for pointing out all the other shortcomings of
    my function. I'll try again taking into account your feedback.

    Regards,
    Paul

    --
    Paul D. Boyle
    boyle@laue.chem .ncsu.edu
    North Carolina State University

    Comment

    • Dan Pop

      #17
      Re: fgets() replacement

      In <c9n8f3$q79$1@u ni00nw.unity.nc su.edu> "Paul D. Boyle" <boyle@laue.che m.ncsu.edu> writes:
      [color=blue]
      >Again, thank-you for pointing out all the other shortcomings of
      >my function. I'll try again taking into account your feedback.[/color]

      OTOH, don't let other people tell you how to invent *your* wheel.
      After all, it's you who's going to ride on it, not them...

      Dan
      --
      Dan Pop
      DESY Zeuthen, RZ group
      Email: Dan.Pop@ifh.de

      Comment

      • Malcolm

        #18
        Re: fgets() replacement


        "Dan Pop" <Dan.Pop@cern.c h> wrote in message[color=blue][color=green]
        > >Again, thank-you for pointing out all the other shortcomings of
        > >my function. I'll try again taking into account your feedback.[/color]
        >
        > OTOH, don't let other people tell you how to invent *your*
        > wheel.
        > After all, it's you who's going to ride on it, not them...
        >[/color]
        But discussing design decisions is a sensible thing to do. The problem is
        that the software engineering side of programming is so immature that you
        will get several opinions on the best way to read a line of text.


        Comment

        • kal

          #19
          Re: fgets() replacement

          Dan.Pop@cern.ch (Dan Pop) wrote in message news:<c9nmbi$oq h$4@sunnews.cer n.ch>...[color=blue]
          > In <c9n8f3$q79$1@u ni00nw.unity.nc su.edu> "Paul D. Boyle" <boyle@laue.che m.ncsu.edu> writes:
          >[color=green]
          > >Again, thank-you for pointing out all the other shortcomings of
          > >my function. I'll try again taking into account your feedback.[/color]
          >
          > OTOH, don't let other people tell you how to invent *your* wheel.
          > After all, it's you who's going to ride on it, not them...
          >
          > Dan[/color]

          1. If one or more functions already available will do the job then
          use those functions. As Hippocrates said: "Art is long, life short,
          experience treacherous, judgement difficult... ." Sorry, I have
          forgotten the full quotation.

          2. When writing general purpose functions, design it so that it
          does the minimum possible extent of work. The simpler the function
          the wider will be its use. The principle to remember is: "if it
          is not necessary for a funtion to do something then it is necessary
          that the function does not do that thing."

          Comment

          • Paul Hsieh

            #20
            Re: fgets() replacement

            "Paul D. Boyle" <boyle@laue.che m.ncsu.edu> wrote:[color=blue]
            > Eric Sosman <Eric.Sosman@su n.com> wrote:
            > : IMHO, a low-level library function should do one thing,
            > : do it well, and do it in a manner that facilitates combining
            > : it with other functions to create grander structures. Or as
            > : my old fencing coach used to admonish me when I got overenthused
            > : with tricky multiple-feint combinations: "Keep It Simple, Stupid."
            >
            > I appreciate your criticisms. I especially agree that the 'int
            > (*validate)(int )' validation is, at best, misplaced to be used by this
            > low level function.[/color]

            Uh ... no. This was probably the best motivated part of your entire
            routine. *fgetc()* is low level. *fread()* is low level. A function
            which inputs a line and doesn't buffer overflow is *NOT* low level.
            See my other comments here:



            The reason why fgets is flawed in the first place was because the
            original designers of the C language made the mistake of thinking
            input was low level.
            [color=blue]
            > [...] I do like, however, the idea of having some way of validating the input
            > which can be simply plugged in without messing with the main flow of the
            > program.[/color]

            Yes. But you need more context to give it the possibility of being
            able to parse. Text input almost always leads to a requirement for
            parsing. Your intuition is correct.
            [color=blue]
            > : far towards the baroque. In effect, USER_DIALOG_H and the
            > : associated macros become part of the function's specification.
            > : That specification now encompasses one return value encoding
            > : three distinguishable states, four function arguments (two
            > : with usage rules not expressible to the compiler), and five
            > : macros. That strikes me as *way* too much for "a replacement
            > : for fgets()."
            >
            > When I was writing the function my idea changed from returning
            > a size_t of the number of bytes read to an error code based
            > returned. I agree that this was muddled by "changing horses
            > in mid stream.[/color]

            So change it to a long. Best of both worlds.
            [color=blue]
            > [...] Based on
            > how I will combine this with other input taking and parsing
            > functions, I am thinking of some thing like:
            >
            > char *get_line( FILE *in, size_t *sz );
            >
            > /* where 'sz' will "return" the number of bytes written */[/color]

            And what if the input size is infinite? (Imagine stdin, and pipe in
            something that simply never issues an EOF?)
            [color=blue]
            > :> #define ERROR_MEMORY (-1)
            > :> #define ERROR_ILLEGAL_C HAR (-2)
            >
            > : Pointless parentheses.
            >
            > I feel embarrassed. Shame is a good teacher. :-)[/color]

            Actually, the "-" sign can be incorrectly interpreted as a subtraction
            as a silent error. I'm sure that in your case that they are
            unnecessary but go look at the include files for any C compiler --
            negative numbers are usually always enclosed in parentheses.

            --
            Paul Hsieh
            Pobox has been discontinued as a separate service, and all existing customers moved to the Fastmail platform.


            Comment

            • Dan Pop

              #21
              Re: fgets() replacement

              In <a5da4cc1.04060 32013.3acd97fa@ posting.google. com> k_amir7@yahoo.c om (kal) writes:
              [color=blue]
              >Dan.Pop@cern.c h (Dan Pop) wrote in message news:<c9nmbi$oq h$4@sunnews.cer n.ch>...[color=green]
              >> In <c9n8f3$q79$1@u ni00nw.unity.nc su.edu> "Paul D. Boyle" <boyle@laue.che m.ncsu.edu> writes:
              >>[color=darkred]
              >> >Again, thank-you for pointing out all the other shortcomings of
              >> >my function. I'll try again taking into account your feedback.[/color]
              >>
              >> OTOH, don't let other people tell you how to invent *your* wheel.
              >> After all, it's you who's going to ride on it, not them...
              >>
              >> Dan[/color]
              >
              >1. If one or more functions already available will do the job then
              >use those functions. As Hippocrates said: "Art is long, life short,
              >experience treacherous, judgement difficult... ." Sorry, I have
              >forgotten the full quotation.
              >
              >2. When writing general purpose functions, design it so that it
              >does the minimum possible extent of work. The simpler the function
              >the wider will be its use. The principle to remember is: "if it
              >is not necessary for a funtion to do something then it is necessary
              >that the function does not do that thing."[/color]

              None of these applies here.

              1. There is no standard function (or functions that simply combined)
              that does the job.

              2. We're talking about a function with a very specific purpose. The hard
              part is not the implementation, but the design. That's why most
              programmers prefer to design it themselves, rather than use some else's
              design. I don't like any of the designs I've seen until now, so if I
              needed such a function, I'd certainly implement my own design...

              Dan
              --
              Dan Pop
              DESY Zeuthen, RZ group
              Email: Dan.Pop@ifh.de

              Comment

              Working...