fgets question

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

    fgets question

    I was talking with someone about fgets and he said that fgets puts the
    \n in a string but not \0. I decided to test this assumption because my
    documentation didn't say if fgets put \0 after a string literal. Strlen was
    what I used to decide the \0 was not added. How can it be added for a
    string? My code.

    int main (void) {
    char input[10];
    fgets (input, sizeof(input), stdin);
    printf ("%i\n", strlen(input));
    }

    One more character than what was typed printf reported.

    Bill



  • Ben Bacarisse

    #2
    Re: fgets question

    "Bill Cunningham" <nospam@nspam.c omwrites:
    I was talking with someone about fgets and he said that fgets puts the
    \n in a string but not \0.
    Where do you meet people to chat about C?
    I decided to test this assumption because my
    documentation didn't say if fgets put \0 after a string literal. Strlen was
    what I used to decide the \0 was not added.
    What made you think that? There must be a null byte or strlen won't
    work.
    How can it be added for a
    string?
    It is there already. If fgets runs out of room it will stop one short
    just so it can always put the terminating null in the buffer. You
    may not get a '\n' but you will always get a 0.
    My code.
    >
    int main (void) {
    char input[10];
    fgets (input, sizeof(input), stdin);
    printf ("%i\n", strlen(input));
    Better is:
    printf ("%i\n", (int)strlen(inp ut));

    since %i needs an int not a size_t. Alternatively use "%zu" as the
    format since you seem to be using somthing close to C99.
    }
    >
    One more character than what was typed printf reported.
    The '\n' is a character. If you type abc and hit return, fgets put
    five things into the input array: 'a', 'b', 'c', '\n' and '\0'. This
    is a four character string and strlen reports 4.

    --
    Ben.

    Comment

    • Jack Klein

      #3
      Re: fgets question

      On Mon, 09 Jun 2008 01:54:12 GMT, "Bill Cunningham" <nospam@nspam.c om>
      wrote in comp.lang.c:
      I was talking with someone about fgets and he said that fgets puts the
      \n in a string but not \0. I decided to test this assumption because my
      documentation didn't say if fgets put \0 after a string literal.
      Who was this person, and what credentials did he have to make you
      think he was right?

      More importantly, what does a string literal have to do with anything?
      fgets() has nothing at all to do with string literals. It reads input
      from a stream. String literals are quoted strings in your source
      code, not input read from a stream.
      Strlen was
      what I used to decide the \0 was not added. How can it be added for a
      string? My code.
      I surely don't understand what you were trying to do above. If you
      had an array of characters that does not contain at least one '\0'
      within the bounds of the array, then it is not a string. Calling
      strlen() on an array of characters that is not a string, due to the
      lack of a '\0', produces undefined behavior. strlen() is for strings,
      not arbitrary arrays of garbage characters.
      int main (void) {
      char input[10];
      fgets (input, sizeof(input), stdin);
      In this call, fgets() will accept up to 9 characters from stdin. Fewer
      if it receives a '\n' before the ninth character.

      It will store these characters into consecutive elements of the array.
      Regardless of whether it stores 9 or fewer characters in the array, it
      will place a '\0' into the array after the last character it stores.

      Here is specifically what the standard says about fgets():

      "The fgets function reads at most one less than the number of
      characters specified by n from the stream pointed to by stream into
      the array pointed to by s. No additional characters are read after a
      new-line character (which is retained) or after end-of-file. A
      null character is written immediately after the last character read
      into the array."

      So your "someone" is wrong in their opinion.
      printf ("%i\n", strlen(input));
      The strlen() function returns a value of type size_t, and since
      printf() is a variadic function, the function call does not perform
      any conversion. "%i" is a conversion specifier for signed int, and
      size_t can never be a signed int since it is always an unsigned type.

      If you need to print a reasonably small value of size_t, you could do
      this:

      printf("%u", (unsigned)strle n(input));
      }
      >
      One more character than what was typed printf reported.
      I can't parse the sentence you have written above.

      It would be much better to:

      1. Show us why you typed into the program

      2. Show us what the output of the program was.

      Regardless of what you think you proved to yourself with your program,
      the fgets() function most surely does produce a '\0' terminated proper
      string, except under two exceptional cases:

      "The fgets function returns s if successful. If end-of-file is
      encountered and no characters have been read into the array, the
      contents of the array remain unchanged and a null pointer is returned.
      If a read error occurs during the operation, the array contents are
      indeterminate and a null pointer is returned."

      Either of these exceptional cases is easily recognized by the fact
      that fgets() returns NULL, instead of returning the pointer that was
      passed in to it.

      --
      Jack Klein
      Home: http://JK-Technology.Com
      FAQs for
      comp.lang.c http://c-faq.com/
      comp.lang.c++ http://www.parashift.com/c++-faq-lite/
      alt.comp.lang.l earn.c-c++

      Comment

      • Bill Cunningham

        #4
        Re: fgets question


        "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
        news:87abhvmjlz .fsf@bsb.me.uk. ..
        Where do you meet people to chat about C?

        On a yahoogroup called c-prog. It's for C++ too.
        >I decided to test this assumption because my
        >documentatio n didn't say if fgets put \0 after a string literal. Strlen
        >was
        >what I used to decide the \0 was not added.
        >
        What made you think that? There must be a null byte or strlen won't
        work.
        >
        >How can it be added for a
        >string?
        >
        It is there already. If fgets runs out of room it will stop one short
        just so it can always put the terminating null in the buffer. You
        may not get a '\n' but you will always get a 0.
        >
        >My code.
        >>
        >int main (void) {
        > char input[10];
        > fgets (input, sizeof(input), stdin);
        > printf ("%i\n", strlen(input));
        >
        Better is:
        printf ("%i\n", (int)strlen(inp ut));
        >
        Oh that looks like a cast. What are you asking printf to do?
        since %i needs an int not a size_t. Alternatively use "%zu" as the
        format since you seem to be using somthing close to C99.
        >
        >}
        >>
        > One more character than what was typed printf reported.
        >
        The '\n' is a character. If you type abc and hit return, fgets put
        five things into the input array: 'a', 'b', 'c', '\n' and '\0'. This
        is a four character string and strlen reports 4.
        >
        --
        Ben.

        Comment

        • Bill Cunningham

          #5
          Re: fgets question


          "Jack Klein" <jackklein@spam cop.netwrote in message
          news:mb4p44po62 5s7hr9odpvms41r 017glm1ch@4ax.c om...
          On Mon, 09 Jun 2008 01:54:12 GMT, "Bill Cunningham" <nospam@nspam.c om>
          wrote in comp.lang.c:
          >
          > I was talking with someone about fgets and he said that fgets puts
          >the
          >\n in a string but not \0. I decided to test this assumption because my
          >documentatio n didn't say if fgets put \0 after a string literal.
          >
          Who was this person, and what credentials did he have to make you
          think he was right?
          >
          More importantly, what does a string literal have to do with anything?
          fgets() has nothing at all to do with string literals. It reads input
          from a stream. String literals are quoted strings in your source
          code, not input read from a stream.
          OK I see then.
          >Strlen was
          >what I used to decide the \0 was not added. How can it be added for a
          >string? My code.
          >
          I surely don't understand what you were trying to do above. If you
          had an array of characters that does not contain at least one '\0'
          within the bounds of the array, then it is not a string. Calling
          strlen() on an array of characters that is not a string, due to the
          lack of a '\0', produces undefined behavior. strlen() is for strings,
          not arbitrary arrays of garbage characters.
          >
          >int main (void) {
          > char input[10];
          > fgets (input, sizeof(input), stdin);
          >
          In this call, fgets() will accept up to 9 characters from stdin. Fewer
          if it receives a '\n' before the ninth character.
          >
          It will store these characters into consecutive elements of the array.
          Regardless of whether it stores 9 or fewer characters in the array, it
          will place a '\0' into the array after the last character it stores.
          [snip]

          So is that extra element that isn't reported then where \0 goes ?

          Bill


          Comment

          • Keith Thompson

            #6
            Re: fgets question

            "Bill Cunningham" <nospam@nspam.c omwrites:
            I was talking with someone about fgets and he said that fgets puts the
            \n in a string but not \0. I decided to test this assumption because my
            documentation didn't say if fgets put \0 after a string literal. Strlen was
            what I used to decide the \0 was not added. How can it be added for a
            string? My code.
            >
            int main (void) {
            char input[10];
            fgets (input, sizeof(input), stdin);
            printf ("%i\n", strlen(input));
            }
            You had "#include <stdio.h>", right?
            One more character than what was typed printf reported.
            I doubt that. For example, if you typed "abc" you almost certainly
            typed 4 character: 'a', 'b', 'c', and the enter key, and strlen(input)
            should have given you 4.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            Nokia
            "We must do something. This is something. Therefore, we must do this."
            -- Antony Jay and Jonathan Lynn, "Yes Minister"

            Comment

            • Keith Thompson

              #7
              Re: fgets question

              "Bill Cunningham" <nospam@nspam.c omwrites:
              "Jack Klein" <jackklein@spam cop.netwrote in message
              news:mb4p44po62 5s7hr9odpvms41r 017glm1ch@4ax.c om...
              >On Mon, 09 Jun 2008 01:54:12 GMT, "Bill Cunningham" <nospam@nspam.c om>
              >wrote in comp.lang.c:
              [...]
              >>int main (void) {
              >> char input[10];
              >> fgets (input, sizeof(input), stdin);
              >>
              >In this call, fgets() will accept up to 9 characters from stdin. Fewer
              >if it receives a '\n' before the ninth character.
              >>
              >It will store these characters into consecutive elements of the array.
              >Regardless of whether it stores 9 or fewer characters in the array, it
              >will place a '\0' into the array after the last character it stores.
              [snip]
              >
              So is that extra element that isn't reported then where \0 goes ?
              The '\0' goes immediately after the last stored character from the
              input, as Jack just told you.

              If you typed 'a', 'b', 'c, and <return(4 character), then fgets()
              will store a total of *five* characters in your array: 'a', 'b', 'c',
              '\n', and '\0'.

              strlen()'s result is the length of the string *excluding* the
              terminating '\0' (in this case, 4).

              --
              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
              Nokia
              "We must do something. This is something. Therefore, we must do this."
              -- Antony Jay and Jonathan Lynn, "Yes Minister"

              Comment

              • pete

                #8
                Re: fgets question

                Ben Bacarisse wrote:
                The '\n' is a character. If you type abc and hit return, fgets put
                five things into the input array: 'a', 'b', 'c', '\n' and '\0'. This
                is a four character string and strlen reports 4.
                It's a five character string; and the length is four.

                --
                pete

                Comment

                • Richard

                  #9
                  Re: fgets question

                  "Bill Cunningham" <nospam@nspam.c omwrites:
                  >>
                  >Better is:
                  > printf ("%i\n", (int)strlen(inp ut));
                  >>
                  >
                  Oh that looks like a cast. What are you asking printf to do?
                  Why not look up the documentation for printf and work it out yourself?

                  Comment

                  • Ben Bacarisse

                    #10
                    Re: fgets question

                    "Bill Cunningham" <nospam@nspam.c omwrites:
                    "Ben Bacarisse" <ben.usenet@bsb .me.ukwrote in message
                    news:87abhvmjlz .fsf@bsb.me.uk. ..
                    >
                    >Where do you meet people to chat about C?
                    >
                    On a yahoogroup called c-prog. It's for C++ too.
                    Ah. I asked because if you could talk to someone face-to-face about C
                    I think you'd make better progress. Online chat is not at all the same.

                    --
                    Ben.

                    Comment

                    • Mark McIntyre

                      #11
                      Re: fgets question

                      Bill Cunningham wrote:
                      > printf ("%i\n", (int)strlen(inp ut));
                      >>
                      >
                      Oh that looks like a cast. What are you asking printf to do?
                      %i requires an int.
                      strlen returns a size_t
                      the two are not necessarily the same width.

                      Comment

                      • CBFalconer

                        #12
                        Re: fgets question

                        pete wrote:
                        Ben Bacarisse wrote:
                        >
                        >The '\n' is a character. If you type abc and hit return, fgets
                        >put five things into the input array: 'a', 'b', 'c', '\n' and
                        >'\0'. This is a four character string and strlen reports 4.
                        >
                        It's a five character string; and the length is four.
                        No, it is a five char array, which will fit in a five (or longer)
                        char array, and it holds a 4 char string.

                        --
                        [mail]: Chuck F (cbfalconer at maineline dot net)
                        [page]: <http://cbfalconer.home .att.net>
                        Try the download section.


                        ** Posted from http://www.teranews.com **

                        Comment

                        • Bill Cunningham

                          #13
                          Re: fgets question


                          "Richard" <rgrdev@gmail.c omwrote in message
                          news:g2iqq5$4em $5@registered.m otzarella.org.. .
                          Why not look up the documentation for printf and work it out yourself?
                          I'm pretty familiar with printf. There are things though I've seen I've
                          wondered about like [] in the first parameter of printf for example. I've
                          not seen those in the docs. And I have some pretty though stuff about
                          printf.

                          Bill


                          Comment

                          • Richard Tobin

                            #14
                            Re: fgets question

                            In article <46h3k.7711$lE3 .5816@trnddc05> ,
                            Bill Cunningham <nospam@nspam.c omwrote:
                            I'm pretty familiar with printf. There are things though I've seen I've
                            >wondered about like [] in the first parameter of printf for example. I've
                            >not seen those in the docs.
                            What sort of "docs" are you reading? You can't expect to write C
                            without a proper reference, and any "doc" that doesn't explain all the
                            conversion specifiers is not a proper reference. Get K&R, or the
                            standard. Even the unix man pages tell you everything you need to
                            know about printf.
                            >And I have some pretty though stuff about printf.
                            No you don't.

                            -- Richard
                            --
                            In the selection of the two characters immediately succeeding the numeral 9,
                            consideration shall be given to their replacement by the graphics 10 and 11 to
                            facilitate the adoption of the code in the sterling monetary area. (X3.4-1963)

                            Comment

                            • Keith Thompson

                              #15
                              Re: fgets question

                              CBFalconer <cbfalconer@yah oo.comwrites:
                              pete wrote:
                              >Ben Bacarisse wrote:
                              >>
                              >>The '\n' is a character. If you type abc and hit return, fgets
                              >>put five things into the input array: 'a', 'b', 'c', '\n' and
                              >>'\0'. This is a four character string and strlen reports 4.
                              >>
                              >It's a five character string; and the length is four.
                              >
                              No, it is a five char array, which will fit in a five (or longer)
                              char array, and it holds a 4 char string.
                              It depends on what you mean by "a 4 char string".

                              A "string" is, by definition,

                              a contiguous sequence of characters terminated by and including
                              the first null character.

                              The "length of a string" is, by definition:

                              the number of bytes preceding the null character

                              (Definitions are from C99 7.1.1p1.)

                              To emphasize the point, the terminating '\0' is part of the string.

                              So the string in question consists of exactly 5 characters, and has a
                              length of 4.

                              --
                              Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                              Nokia
                              "We must do something. This is something. Therefore, we must do this."
                              -- Antony Jay and Jonathan Lynn, "Yes Minister"

                              Comment

                              Working...