scanf problem with intaking a string *PLS. HELP*

Discussion in 'C Programming' started by Radith, Jul 31, 2005.

  1. Radith

    Radith Guest

    HI all;

    I have created a program just to get an understanding of strcpy. (still an
    amateur developer).

    I use scanf("%s", &first) in order to get the input to the variable first
    (which is char first[]).

    Then I go strcpy(second, first). This is just to demonstrate the strcpy
    function for myself and it (as far as I know) copies what's in first to
    second.

    The problem is: * When a user uses spaces in his/her input (e.g. "Hello
    World")
    --> Only "Hello" will be displayed.

    Now I have made sure the array has ample size; I just dont know what's
    wrong?

    I unfortunately have deleted the source code by mistake (as I was
    frustrated); so I can't supply it here; If y'all really need it I wouldn't
    ming writing it out again but I think y'all can have a pretty good
    understanding from my descriptions.

    Please Help. Thanks a lot for it in advance.
     
    Radith, Jul 31, 2005
    #1
    1. Advertising

  2. Radith

    Ben Pfaff Guest

    "Radith" <> writes:

    > I use scanf("%s", &first) in order to get the input to the variable first
    > (which is char first[]).
    >
    > Then I go strcpy(second, first). This is just to demonstrate the strcpy
    > function for myself and it (as far as I know) copies what's in first to
    > second.
    >
    > The problem is: * When a user uses spaces in his/her input (e.g. "Hello
    > World")
    > --> Only "Hello" will be displayed.


    This is because %s only reads a single word. It will skip
    leading white space, but after that white space causes it to stop
    reading.
    --
    "When I have to rely on inadequacy, I prefer it to be my own."
    --Richard Heathfield
     
    Ben Pfaff, Jul 31, 2005
    #2
    1. Advertising

  3. Radith

    Malcolm Guest

    "Radith" <> wrote
    >
    > I use scanf("%s", &first) in order to get the input to the variable first
    > (which is char first[]).
    >

    scanf("%s", ptr);

    will only read the first word (string of characters separated by whitespace)
    into the bufer pointed to by ptr.
    You can read a whole line with gets(). Unfortunately the function is flawed,
    because the buffer will overrun, probably causing a crash, if the user types
    in too many characters. fgets() is even worse if used incorrectly - input is
    silently truncated. Why is that worse? Because wrong results are usually
    worse than no results. However you can build a solid input function on top
    of fgets(), but it is needlessly complicated.
    So regrettably there is no easy way of getting a line from the user in ISO
    C.
     
    Malcolm, Jul 31, 2005
    #3
  4. "Malcolm" <> writes:
    > "Radith" <> wrote
    >>
    >> I use scanf("%s", &first) in order to get the input to the variable first
    >> (which is char first[]).
    >>

    > scanf("%s", ptr);
    >
    > will only read the first word (string of characters separated by whitespace)
    > into the bufer pointed to by ptr.
    > You can read a whole line with gets(). Unfortunately the function is flawed,
    > because the buffer will overrun, probably causing a crash, if the user types
    > in too many characters. fgets() is even worse if used incorrectly - input is
    > silently truncated. Why is that worse? Because wrong results are usually
    > worse than no results. However you can build a solid input function on top
    > of fgets(), but it is needlessly complicated.
    > So regrettably there is no easy way of getting a line from the user in ISO
    > C.


    fgets() is worse than gets()?

    Nonsense.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Aug 1, 2005
    #4
  5. Radith

    Martijn Guest

    > [snipped] If y'all really need it [snipped]

    Is that your truck in MUD95?

    Alright, alright, I'll start contributing serious responses again.

    --
    Martijn
    http://www.sereneconcepts.nl
     
    Martijn, Aug 1, 2005
    #5
  6. Radith

    Michael Mair Guest

    Keith Thompson wrote:
    > "Malcolm" <> writes:
    >
    >>"Radith" <> wrote
    >>
    >>>I use scanf("%s", &first) in order to get the input to the variable first
    >>>(which is char first[]).
    >>>

    >>
    >>scanf("%s", ptr);
    >>
    >>will only read the first word (string of characters separated by whitespace)
    >>into the bufer pointed to by ptr.
    >>You can read a whole line with gets(). Unfortunately the function is flawed,
    >>because the buffer will overrun, probably causing a crash, if the user types
    >>in too many characters. fgets() is even worse if used incorrectly - input is
    >>silently truncated. Why is that worse? Because wrong results are usually
    >>worse than no results. However you can build a solid input function on top
    >>of fgets(), but it is needlessly complicated.
    >>So regrettably there is no easy way of getting a line from the user in ISO
    >>C.

    >
    >
    > fgets() is worse than gets()?
    >
    > Nonsense.


    Well, in a way, it is: It is the closest you can get to a sensible
    text input function but falls short, unnecessarily and nastily.
    If you consider a function more broken which does not invoke UB
    (and quite often segfaults to tell you where you went wrong)
    instead of silently truncating and upsetting everything in a
    hard-to-catch way, then you can arrive at this conclusion.
    IMO, fgets() with sensible return values to communicate, say
    EOF/Error/NoNewLineEncountered/NewLineEncountered, would be
    quite alright.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Aug 1, 2005
    #6
  7. Michael Mair wrote:
    > Keith Thompson wrote:


    <snip>

    > >
    > >
    > > fgets() is worse than gets()?
    > >
    > > Nonsense.

    >
    > Well, in a way, it is: It is the closest you can get to a sensible
    > text input function but falls short, unnecessarily and nastily.
    > If you consider a function more broken which does not invoke UB
    > (and quite often segfaults to tell you where you went wrong)
    > instead of silently truncating and upsetting everything in a
    > hard-to-catch way, then you can arrive at this conclusion.

    <snip>

    Huh? UB nearly universally "[upsets] everything in a hard-to-catch
    way". Even worse, it often results in security holes.

    Well-defined but annoying behavior is certainly not worse, at least in
    the sense of the word I am accustomed to.


    Mark F. Haigh
     
    Mark F. Haigh, Aug 1, 2005
    #7
  8. On Mon, 01 Aug 2005 08:51:23 +0200, Michael Mair
    <> wrote:

    > Keith Thompson wrote:
    >> "Malcolm" <> writes:
    >>
    >>>"Radith" <> wrote
    >>>
    >>>>I use scanf("%s", &first) in order to get the input to the variable first
    >>>>(which is char first[]).
    >>>>
    >>>
    >>>scanf("%s", ptr);
    >>>
    >>>will only read the first word (string of characters separated by whitespace)
    >>>into the bufer pointed to by ptr.
    >>>You can read a whole line with gets(). Unfortunately the function is flawed,
    >>>because the buffer will overrun, probably causing a crash, if the user types
    >>>in too many characters. fgets() is even worse if used incorrectly - input is
    >>>silently truncated. Why is that worse? Because wrong results are usually
    >>>worse than no results. However you can build a solid input function on top
    >>>of fgets(), but it is needlessly complicated.
    >>>So regrettably there is no easy way of getting a line from the user in ISO
    >>>C.

    >>
    >> fgets() is worse than gets()?
    >>
    >> Nonsense.

    >
    > Well, in a way, it is: It is the closest you can get to a sensible
    > text input function but falls short, unnecessarily and nastily.


    OK, so it's not a perfect interface, lots of the C library isn't a
    perfect interface. Whether it is 'necessary' to have had that interface
    is a matter of opinion, but most of the I/O interface wasn't designed,
    it "jest growed". It's certainly perfectly usable.

    > If you consider a function more broken which does not invoke UB
    > (and quite often segfaults to tell you where you went wrong)
    > instead of silently truncating and upsetting everything in a
    > hard-to-catch way, then you can arrive at this conclusion.


    I have never had fgets() segfault, except when passing it invalid
    parameters. How have you done it? If you give it a valid file pointer,
    valid pointer to a data area and a correct length (no greater than the
    size of the data area) then if it segfaults you have a faulty
    implementation.

    fgets() doesn't 'truncate', it simply stops inputting when the buffer is
    full. Doing "if (strchr(buffer, '\n'))" will detect whether the line
    was complete at that point (strlen() would do as well). You can then
    decide whether you want to discard the rest of the data, increase the
    buffer size, or whatever. If you don't bother testing then your program
    is broken, no more or less than if you ignore returned status.

    > IMO, fgets() with sensible return values to communicate, say
    > EOF/Error/NoNewLineEncountered/NewLineEncountered, would be
    > quite alright.


    All that information is available. You can call feof/ferror on the
    input stream (fgets() will return NULL if it didn't get anything) and
    you can test for newline as above.

    Or of course you can write your own input function with the behaviour
    you like, it's not hard (indeed, I've rewritten such functions many
    times because it was faster than digging out the code I'd written
    before).

    Chris C
     
    Chris Croughton, Aug 1, 2005
    #8
  9. On Sun, 31 Jul 2005 16:36:11 +0000, Malcolm wrote:

    >
    > "Radith" <> wrote
    >>
    >> I use scanf("%s", &first) in order to get the input to the variable first
    >> (which is char first[]).
    >>

    > scanf("%s", ptr);
    >
    > will only read the first word (string of characters separated by whitespace)
    > into the bufer pointed to by ptr.
    > You can read a whole line with gets(). Unfortunately the function is flawed,
    > because the buffer will overrun, probably causing a crash, if the user types
    > in too many characters.


    Correct.

    > fgets() is even worse if used incorrectly - input is
    > silently truncated. Why is that worse? Because wrong results are usually
    > worse than no results.


    Often correct input has limited length. In which case fgets() (given a
    suitable arguments) will only go "wrong" on invalid input, which is
    perfectly reasonable.

    Also you imply that gets() would give no results, which is wrong. fgets()
    has well defined behaviour on too long input even if it isn't the
    behaviour you want, gets() has undefined behaviour. Both can give results,
    the difference is that with fgets() the results are well defined and quite
    possibly recoverable, with gets() the whole program ceases to be
    predictable. There is no sense in which fgets() is worse than gets().

    > However you can build a solid input function on top
    > of fgets(), but it is needlessly complicated.
    > So regrettably there is no easy way of getting a line from the user in ISO
    > C.


    It is easy as long as you stipulate that valid lines must not exceed a
    certain size. fgets() will still handle valid input fine and invalid input
    in a controlled way.

    Lawrence
     
    Lawrence Kirby, Aug 1, 2005
    #9
  10. Radith

    John Bode Guest

    Michael Mair wrote:
    > Keith Thompson wrote:
    > > "Malcolm" <> writes:
    > >
    > >>"Radith" <> wrote
    > >>
    > >>>I use scanf("%s", &first) in order to get the input to the variable first
    > >>>(which is char first[]).
    > >>>
    > >>
    > >>scanf("%s", ptr);
    > >>
    > >>will only read the first word (string of characters separated by whitespace)
    > >>into the bufer pointed to by ptr.
    > >>You can read a whole line with gets(). Unfortunately the function is flawed,
    > >>because the buffer will overrun, probably causing a crash, if the user types
    > >>in too many characters. fgets() is even worse if used incorrectly - input is
    > >>silently truncated. Why is that worse? Because wrong results are usually
    > >>worse than no results. However you can build a solid input function on top
    > >>of fgets(), but it is needlessly complicated.
    > >>So regrettably there is no easy way of getting a line from the user in ISO
    > >>C.

    > >
    > >
    > > fgets() is worse than gets()?
    > >
    > > Nonsense.

    >
    > Well, in a way, it is: It is the closest you can get to a sensible
    > text input function but falls short, unnecessarily and nastily.
    > If you consider a function more broken which does not invoke UB
    > (and quite often segfaults to tell you where you went wrong)
    > instead of silently truncating and upsetting everything in a
    > hard-to-catch way, then you can arrive at this conclusion.
    > IMO, fgets() with sensible return values to communicate, say
    > EOF/Error/NoNewLineEncountered/NewLineEncountered, would be
    > quite alright.
    >


    Well, even though the function interface itself doesn't provide these
    values, they can be tested for relatively easily:

    if (fgets(buffer, sizeof buffer, stream))
    {
    if (strchr(buffer, '\n'))
    {
    /* NewLineEncountered */
    }
    else
    {
    /* NoNewLineEncountered */
    }
    }
    else
    {
    if (feof(stream))
    {
    /* EOF */
    }
    else
    {
    /* Error */
    }
    }

    I mean, The C Way is for the library to do ~90% of what you need it to,
    and then fill in the rest by hand. No, I'm not bitter, really.

    For all its flaws, fgets() has one chief advantage over gets() -- you
    don't run the risk of crashing your program or opening a security hole
    *every* time you call it.

    >
    > Cheers
    > Michael
    > --
    > E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    John Bode, Aug 1, 2005
    #10
  11. Radith

    Michael Mair Guest

    Mark F. Haigh wrote:
    > Michael Mair wrote:
    >
    >>Keith Thompson wrote:

    >
    > <snip>
    >
    >>>fgets() is worse than gets()?
    >>>
    >>>Nonsense.

    >>
    >>Well, in a way, it is: It is the closest you can get to a sensible
    >>text input function but falls short, unnecessarily and nastily.
    >>If you consider a function more broken which does not invoke UB

    ^^^
    one "not" too many :-(

    >>(and quite often segfaults to tell you where you went wrong)
    >>instead of silently truncating and upsetting everything in a
    >>hard-to-catch way, then you can arrive at this conclusion.

    >
    > <snip>
    >
    > Huh? UB nearly universally "[upsets] everything in a hard-to-catch
    > way". Even worse, it often results in security holes.
    >
    > Well-defined but annoying behavior is certainly not worse, at least in
    > the sense of the word I am accustomed to.


    I just tried to explain how one might regard fgets() as worse than
    gets() -- and failed.
    Personally, I do not use either and work with getc()- or fread()-based
    input or fscanf() if I feel daring.
    What I meant is that it is sometimes easier to find a gets() gone wild
    than a fgets() treading down the semantics.
    The original statement did not come from me but I understand the
    sentiment behind it very well.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Aug 1, 2005
    #11
  12. Radith

    Michael Mair Guest

    Chris Croughton wrote:
    > On Mon, 01 Aug 2005 08:51:23 +0200, Michael Mair
    > <> wrote:
    >
    >>Keith Thompson wrote:
    >>
    >>>"Malcolm" <> writes:
    >>>
    >>>>"Radith" <> wrote
    >>>>
    >>>>>I use scanf("%s", &first) in order to get the input to the variable first
    >>>>>(which is char first[]).
    >>>>
    >>>>scanf("%s", ptr);
    >>>>
    >>>>will only read the first word (string of characters separated by whitespace)
    >>>>into the bufer pointed to by ptr.
    >>>>You can read a whole line with gets(). Unfortunately the function is flawed,
    >>>>because the buffer will overrun, probably causing a crash, if the user types
    >>>>in too many characters. fgets() is even worse if used incorrectly - input is
    >>>>silently truncated. Why is that worse? Because wrong results are usually
    >>>>worse than no results. However you can build a solid input function on top
    >>>>of fgets(), but it is needlessly complicated.
    >>>>So regrettably there is no easy way of getting a line from the user in ISO
    >>>>C.
    >>>
    >>>fgets() is worse than gets()?
    >>>
    >>>Nonsense.

    >>
    >>Well, in a way, it is: It is the closest you can get to a sensible
    >>text input function but falls short, unnecessarily and nastily.

    >
    > OK, so it's not a perfect interface, lots of the C library isn't a
    > perfect interface. Whether it is 'necessary' to have had that interface
    > is a matter of opinion, but most of the I/O interface wasn't designed,
    > it "jest growed". It's certainly perfectly usable.


    'Tis, for some values of "perfectly".

    >>If you consider a function more broken which does not invoke UB

    ^^^
    one "not" too many :-(

    >>(and quite often segfaults to tell you where you went wrong)
    >>instead of silently truncating and upsetting everything in a
    >>hard-to-catch way, then you can arrive at this conclusion.

    >
    > I have never had fgets() segfault, except when passing it invalid
    > parameters. How have you done it? If you give it a valid file pointer,
    > valid pointer to a data area and a correct length (no greater than the
    > size of the data area) then if it segfaults you have a faulty
    > implementation.


    Umh, see above (one not too many) and <>,
    my reply to Mark F. Haigh.
    I head gets() segfault in other people's code which was much easier
    to find than fgets()-related problems.

    > fgets() doesn't 'truncate', it simply stops inputting when the buffer is
    > full. Doing "if (strchr(buffer, '\n'))" will detect whether the line
    > was complete at that point (strlen() would do as well). You can then
    > decide whether you want to discard the rest of the data, increase the
    > buffer size, or whatever. If you don't bother testing then your program
    > is broken, no more or less than if you ignore returned status.


    This is, as in <> mentioned, the reason
    why I do not use fgets()...

    >>IMO, fgets() with sensible return values to communicate, say
    >>EOF/Error/NoNewLineEncountered/NewLineEncountered, would be
    >>quite alright.

    >
    > All that information is available. You can call feof/ferror on the
    > input stream (fgets() will return NULL if it didn't get anything) and
    > you can test for newline as above.
    >
    > Or of course you can write your own input function with the behaviour
    > you like, it's not hard (indeed, I've rewritten such functions many
    > times because it was faster than digging out the code I'd written
    > before).


    Yep, and usually, getc() based input code is clearer than catching all
    the indirect error returns of fgets().

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Aug 1, 2005
    #12
  13. Radith

    Michael Mair Guest

    John Bode wrote:
    > Michael Mair wrote:
    >
    >>Keith Thompson wrote:
    >>
    >>>"Malcolm" <> writes:
    >>>
    >>>>"Radith" <> wrote
    >>>>
    >>>>>I use scanf("%s", &first) in order to get the input to the variable first
    >>>>>(which is char first[]).
    >>>>
    >>>>scanf("%s", ptr);
    >>>>
    >>>>will only read the first word (string of characters separated by whitespace)
    >>>>into the bufer pointed to by ptr.
    >>>>You can read a whole line with gets(). Unfortunately the function is flawed,
    >>>>because the buffer will overrun, probably causing a crash, if the user types
    >>>>in too many characters. fgets() is even worse if used incorrectly - input is
    >>>>silently truncated. Why is that worse? Because wrong results are usually
    >>>>worse than no results. However you can build a solid input function on top
    >>>>of fgets(), but it is needlessly complicated.
    >>>>So regrettably there is no easy way of getting a line from the user in ISO
    >>>>C.
    >>>
    >>>fgets() is worse than gets()?
    >>>
    >>>Nonsense.

    >>
    >>Well, in a way, it is: It is the closest you can get to a sensible
    >>text input function but falls short, unnecessarily and nastily.
    >>If you consider a function more broken which does not invoke UB
    >>(and quite often segfaults to tell you where you went wrong)
    >>instead of silently truncating and upsetting everything in a
    >>hard-to-catch way, then you can arrive at this conclusion.
    >>IMO, fgets() with sensible return values to communicate, say
    >>EOF/Error/NoNewLineEncountered/NewLineEncountered, would be
    >>quite alright.

    >
    > Well, even though the function interface itself doesn't provide these
    > values, they can be tested for relatively easily:
    >
    > if (fgets(buffer, sizeof buffer, stream))
    > {
    > if (strchr(buffer, '\n'))
    > {
    > /* NewLineEncountered */
    > }
    > else
    > {
    > /* NoNewLineEncountered */
    > }
    > }
    > else
    > {
    > if (feof(stream))
    > {
    > /* EOF */
    > }
    > else
    > {
    > /* Error */
    > }
    > }
    >
    > I mean, The C Way is for the library to do ~90% of what you need it to,
    > and then fill in the rest by hand. No, I'm not bitter, really.
    >
    > For all its flaws, fgets() has one chief advantage over gets() -- you
    > don't run the risk of crashing your program or opening a security hole
    > *every* time you call it.


    Thanks for writing it out. See my other two replies to see how my
    explanation failed to make sense.
    However, the above demonstrates why so many people use fgets() in
    the wrong way :-/ As mentioned before: getc() produces clearer code.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Aug 1, 2005
    #13
  14. Michael Mair <> writes:
    [...]
    > I just tried to explain how one might regard fgets() as worse than
    > gets() -- and failed.
    > Personally, I do not use either and work with getc()- or fread()-based
    > input or fscanf() if I feel daring.
    > What I meant is that it is sometimes easier to find a gets() gone wild
    > than a fgets() treading down the semantics.
    > The original statement did not come from me but I understand the
    > sentiment behind it very well.


    There are two separate issues here.

    The first is that gets() is broken, and cannot be used safely.
    It should be removed from the language (in my opinion, and in the
    opinion of many others).

    The second is that fgets() has some problems, and can be used either
    correctly or incorrectly.

    fgets() may be a problem, but gets() is certainly not the solution.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Aug 1, 2005
    #14
  15. Radith

    CBFalconer Guest

    Michael Mair wrote:
    > John Bode wrote:
    >

    .... snip ...
    >>
    >> Well, even though the function interface itself doesn't provide
    >> these values, they can be tested for relatively easily:
    >>

    /* minor editing to emphasize 3 major possibilities - cbf */
    >> if (fgets(buffer, sizeof buffer, stream)) {
    >> if (strchr(buffer, '\n')) {
    >> /* NewLineEncountered */
    >> }
    >> else {
    >> /* NoNewLineEncountered */
    >> }
    >> }
    >> else if (feof(stream)) {
    >> /* EOF */
    >> }
    >> else {
    >> /* Error */
    >> }
    >>

    .... snip ...
    > However, the above demonstrates why so many people use fgets() in
    > the wrong way :-/ As mentioned before: getc() produces clearer code.


    My ggets package uses fgets for actual input, but could just as
    well use getc. In some systems the results may be more efficient,
    depending primarily on whether getc is actually a macro operating
    directoy on the stream buffer. However that is not likely to
    matter in a function used primarily for interactive input. It
    might well reduce the volume of library code needed to link.

    To me ggets presents the right interface. It is simple, it always
    gets complete lines, and the terminal '\n' is always stripped. Its
    error return allows for malloc failure, completion, and the EOF or
    error condition (which the user can separate if needed).

    int ggets(char **line);
    or
    int fggets(char **line, FILE *f);

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Aug 1, 2005
    #15
  16. Keith Thompson wrote:

    <snip>

    >
    > fgets() may be a problem, but gets() is certainly not the solution.


    Well put. That'll go in the quotes file.


    Mark F. Haigh
     
    Mark F. Haigh, Aug 2, 2005
    #16
  17. Radith

    David Mathog Guest

    John Bode wrote:

    >
    >
    > Well, even though the function interface itself doesn't provide these
    > values, they can be tested for relatively easily:
    >
    > if (fgets(buffer, sizeof buffer, stream))
    > {
    > if (strchr(buffer, '\n'))


    Sure that works but it's horribly inefficient. What if buffer
    is 2M in length, why should the program have to (re)scan it
    when fgets knew perfectly well that it truncated the buffer? Clearly
    a sane replacement for fgets would return a status
    value indicating that the truncation took place. I often
    wonder just what the designer of fgets was thinking when he
    (she?) chose the return value. Clearly a simple int
    return value something like this would have worked much
    better:

    >=0 number of characters read (EOL character stripped)

    -1 EOF
    -2 Read Error
    -3 Buffer Full
    (or
    N+1 Buffer Full, where N is the number of characters in the buffer)

    Even more amazing to me is that subsequent C standards have not
    introduced this "sfgets" (sane fgets) so that future C code
    wouldn't be forever hobbled by the poor design choices made for fgets.

    Regards,

    David Mathog
     
    David Mathog, Aug 2, 2005
    #17
  18. Radith

    CBFalconer Guest

    David Mathog wrote:
    > John Bode wrote:
    >
    >> Well, even though the function interface itself doesn't provide
    >> these values, they can be tested for relatively easily:
    >>
    >> if (fgets(buffer, sizeof buffer, stream))
    >> {
    >> if (strchr(buffer, '\n'))

    >
    > Sure that works but it's horribly inefficient. What if buffer
    > is 2M in length, why should the program have to (re)scan it
    > when fgets knew perfectly well that it truncated the buffer?
    > Clearly a sane replacement for fgets would return a status
    > value indicating that the truncation took place. I often
    > wonder just what the designer of fgets was thinking when he
    > (she?) chose the return value. Clearly a simple int
    > return value something like this would have worked much
    > better:
    >
    > >=0 number of characters read (EOL character stripped)

    > -1 EOF
    > -2 Read Error
    > -3 Buffer Full
    > (or
    > N+1 Buffer Full, where N is the number of characters in the
    > buffer)
    >
    > Even more amazing to me is that subsequent C standards have not
    > introduced this "sfgets" (sane fgets) so that future C code
    > wouldn't be forever hobbled by the poor design choices made for
    > fgets.


    Don't worry about it. Just get and use the portable public domain:

    <http://cbfalconer.home.att.net/download/ggets.zip>

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
     
    CBFalconer, Aug 2, 2005
    #18
  19. Radith

    Michael Mair Guest

    CBFalconer wrote:
    > Michael Mair wrote:
    >
    >>John Bode wrote:
    >>

    >
    > ... snip ...
    >
    >>>Well, even though the function interface itself doesn't provide
    >>>these values, they can be tested for relatively easily:
    >>>

    >
    > /* minor editing to emphasize 3 major possibilities - cbf */
    >
    >>>if (fgets(buffer, sizeof buffer, stream)) {
    >>> if (strchr(buffer, '\n')) {
    >>> /* NewLineEncountered */
    >>> }
    >>> else {
    >>> /* NoNewLineEncountered */
    >>> }
    >>>}
    >>>else if (feof(stream)) {
    >>> /* EOF */
    >>>}
    >>>else {
    >>> /* Error */
    >>>}
    >>>

    >
    > ... snip ...
    >
    >>However, the above demonstrates why so many people use fgets() in
    >>the wrong way :-/ As mentioned before: getc() produces clearer code.

    >
    >
    > My ggets package uses fgets for actual input, but could just as
    > well use getc. In some systems the results may be more efficient,
    > depending primarily on whether getc is actually a macro operating
    > directoy on the stream buffer. However that is not likely to
    > matter in a function used primarily for interactive input. It
    > might well reduce the volume of library code needed to link.
    >
    > To me ggets presents the right interface. It is simple, it always
    > gets complete lines, and the terminal '\n' is always stripped. Its
    > error return allows for malloc failure, completion, and the EOF or
    > error condition (which the user can separate if needed).
    >
    > int ggets(char **line);
    > or
    > int fggets(char **line, FILE *f);


    To complete the advertisement:

    <http://cbfalconer.home.att.net/download/ggets.zip>

    It is certainly a nice, portable and available replacement.

    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Aug 2, 2005
    #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. James Bond
    Replies:
    0
    Views:
    541
    James Bond
    Aug 3, 2004
  2. Rahul S.
    Replies:
    3
    Views:
    612
    Flash Gordon
    Nov 1, 2004
  3. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc.

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Feb 16, 2006, in forum: C Programming
    Replies:
    185
    Views:
    3,453
    those who know me have no need of my name
    Apr 3, 2006
  4. =?ISO-8859-1?Q?Martin_J=F8rgensen?=

    difference between scanf("%i") and scanf("%d") ??? perhaps bug inVS2005?

    =?ISO-8859-1?Q?Martin_J=F8rgensen?=, Apr 26, 2006, in forum: C Programming
    Replies:
    18
    Views:
    691
    Richard Bos
    May 2, 2006
  5. Replies:
    1
    Views:
    289
    RedGrittyBrick
    Jan 2, 2008
Loading...

Share This Page