C and strings

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

    #1

    C and strings

    Hi,

    I am new to c and am having trouble with strings can anyone give me some
    quick pointers or point me to a good c strings tutorial? Below is a
    program I am working on.

    Kind Regards,
    Anthony Irwin

    #include <stdio.h>

    char teststring[40] = "test string now";
    char teststring1[40];

    int main() {
    printf("teststr ing = %s", teststring);
    strcpy(teststri ng1, teststring);
    printf("\ntests tring1 = %s", teststring1);

    /* How can I assign a new value to teststring say
    * the value "I changed string text" */

    printf("\n\nI changed teststring to = %s\n", teststring);

    return 0;
    }
  • John

    #2
    Re: C and strings

    On Thu, 11 Aug 2005 09:54:28 +1000, Anthony Irwin wrote:
    [color=blue]
    > Hi,
    >
    > I am new to c and am having trouble with strings can anyone give me some
    > quick pointers or point me to a good c strings tutorial? Below is a
    > program I am working on.
    >
    > Kind Regards,
    > Anthony Irwin
    >
    > #include <stdio.h>
    >
    > char teststring[40] = "test string now";
    > char teststring1[40];
    >
    > int main() {
    > printf("teststr ing = %s", teststring);
    > strcpy(teststri ng1, teststring);
    > printf("\ntests tring1 = %s", teststring1);
    >
    > /* How can I assign a new value to teststring say
    > * the value "I changed string text" */[/color]
    /* What you mean? just call strcpy() again! */
    strcpy(teststri ng, "I changed string text");[color=blue]
    >
    > printf("\n\nI changed teststring to = %s\n", teststring);
    >
    > return 0;
    > }[/color]

    Comment

    • John Bode

      #3
      Re: C and strings


      Anthony Irwin wrote:[color=blue]
      > Hi,
      >
      > I am new to c and am having trouble with strings can anyone give me some
      > quick pointers or point me to a good c strings tutorial? Below is a
      > program I am working on.
      >
      > Kind Regards,
      > Anthony Irwin
      >
      > #include <stdio.h>
      >
      > char teststring[40] = "test string now";
      > char teststring1[40];
      >
      > int main() {
      > printf("teststr ing = %s", teststring);
      > strcpy(teststri ng1, teststring);
      > printf("\ntests tring1 = %s", teststring1);
      >
      > /* How can I assign a new value to teststring say
      > * the value "I changed string text" */
      >
      > printf("\n\nI changed teststring to = %s\n", teststring);
      >
      > return 0;
      > }[/color]

      strncpy(teststr ing, "I changed string text", sizeof teststring-1);

      or

      sprintf(teststr ing, "%.*s", sizeof teststring-1, "I changed string
      text");

      The conversion specifier "%.Ns" indicates that no more than N
      characters should be written; for example, we could have written
      "%.39s". Using * instead of a constant means that N is specified in
      one of the arguments to printf() (in this case, by the expression
      sizeof teststring-1).

      The expression "sizeof teststring-1" gives the size of the destination
      buffer, less one character for a 0 terminator, so in both cases, no
      more than 39 characters are being written to teststring.

      Comment

      • Anthony Irwin

        #4
        Re: C and strings

        Thanks for the reply guys. For some reason I thought you had to use
        variables with strcpy.

        Kind Regards,
        Anthony Irwin

        Comment

        • kernelxu@hotmail.com

          #5
          Re: C and strings

          I agree with John.
          using strncpy() is better than strcpy().

          if teststring1 doesn't have enough room for the copied string , there
          will be a overflow.
          strncpy() reminds you pay attention to it.

          Comment

          • Keith Thompson

            #6
            Re: C and strings

            kernelxu@hotmai l.com writes:[color=blue]
            > I agree with John.
            > using strncpy() is better than strcpy().
            >
            > if teststring1 doesn't have enough room for the copied string , there
            > will be a overflow.
            > strncpy() reminds you pay attention to it.[/color]

            First, please provide some context when you post a followup. Search
            for "google broken reply link" in this newsgroup for many many copies
            of the same explanation.

            Second, strncpy() isn't as superior to strcpy() as you might think.
            It does let you limit the number of bytes to copy, but its behavior is
            questionable in many cases. For example, if you do
            strncpy(s, "hello", 5);
            it will copy exactly 5 characters to s; it will *not* copy the
            terminating '\0' character. On the other hand, if you do
            strncpy(s, "hello", 500);
            (assuming that s is big enough) it will pad the target with null
            characters, wastefully writing 495 '\0' characters when one would have
            been sufficient.

            The strncpy() function, despite the name, doesn't consistently work
            with C strings; it works with a specific data structure that's rarely
            used these days, a '\0'-padded character array in which the trailing
            '\0' is optional if the actual data fills the array. (This was used
            by early versions of Unix to store file names, back when they were
            limited to 14 characters.)

            strcpy() is safe *if* you first confirm that the target is big enough
            to hold the string being copied. strncpy() can avoid array overflow
            bugs, but at the expense of introducing other problems.

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

            Comment

            • bwaichu@yahoo.com

              #7
              Re: C and strings

              If you are looking for safer, look at the strlcpy() over at openBSD or
              write one like it.

              Brian

              Comment

              • John

                #8
                Re: C and strings

                On Wed, 10 Aug 2005 17:31:51 -0700, John Bode wrote:
                [color=blue]
                >
                > Anthony Irwin wrote:[color=green]
                >> Hi,
                >>
                >> I am new to c and am having trouble with strings can anyone give me some
                >> quick pointers or point me to a good c strings tutorial? Below is a
                >> program I am working on.
                >>
                >> Kind Regards,
                >> Anthony Irwin
                >>
                >> #include <stdio.h>
                >>
                >> char teststring[40] = "test string now";
                >> char teststring1[40];
                >>
                >> int main() {
                >> printf("teststr ing = %s", teststring);
                >> strcpy(teststri ng1, teststring);
                >> printf("\ntests tring1 = %s", teststring1);
                >>
                >> /* How can I assign a new value to teststring say
                >> * the value "I changed string text" */
                >>
                >> printf("\n\nI changed teststring to = %s\n", teststring);
                >>
                >> return 0;
                >> }[/color]
                >
                > strncpy(teststr ing, "I changed string text", sizeof teststring-1);[/color]
                teststring[sizeof(teststri ng)-1] = '\0';
                /* This is safe, if strncpy will use at most 40
                characters from src string. the dest string will not be
                null-terminated. */[color=blue]
                >
                > or
                >
                > sprintf(teststr ing, "%.*s", sizeof teststring-1, "I changed string
                > text");
                >
                > The conversion specifier "%.Ns" indicates that no more than N characters
                > should be written; for example, we could have written "%.39s". Using *
                > instead of a constant means that N is specified in one of the arguments
                > to printf() (in this case, by the expression sizeof teststring-1).
                >
                > The expression "sizeof teststring-1" gives the size of the destination
                > buffer, less one character for a 0 terminator, so in both cases, no more
                > than 39 characters are being written to teststring.[/color]

                Comment

                • Anthony Irwin

                  #9
                  Re: C and strings

                  On Wed, 10 Aug 2005 18:01:54 -0700, kernelxu wrote:
                  [color=blue]
                  > I agree with John.
                  > using strncpy() is better than strcpy().
                  >
                  > if teststring1 doesn't have enough room for the copied string , there
                  > will be a overflow.
                  > strncpy() reminds you pay attention to it.[/color]

                  Ok so I do the following:

                  strncpy(teststr ing, "I changed teststring value", sizeof teststring -1);

                  Will that put the null terminator on the string or should I do the
                  following:

                  strncpy(teststr ing, "I changed teststring value\0", sizeof teststring -1);


                  Thanks again for the replys.

                  Kind Regards,
                  Anthony Irwin

                  Comment

                  • Anthony Irwin

                    #10
                    Re: C and strings

                    On Thu, 11 Aug 2005 01:20:02 +0000, Keith Thompson wrote:

                    <snip>[color=blue]
                    > terminating '\0' character. On the other hand, if you do
                    > strncpy(s, "hello", 500);
                    > (assuming that s is big enough) it will pad the target with null
                    > characters, wastefully writing 495 '\0' characters when one would have
                    > been sufficient.
                    >
                    > The strncpy() function, despite the name, doesn't consistently work
                    > with C strings; it works with a specific data structure that's rarely
                    > used these days, a '\0'-padded character array in which the trailing
                    > '\0' is optional if the actual data fills the array. (This was used
                    > by early versions of Unix to store file names, back when they were
                    > limited to 14 characters.)
                    >
                    > strcpy() is safe *if* you first confirm that the target is big enough
                    > to hold the string being copied. strncpy() can avoid array overflow
                    > bugs, but at the expense of introducing other problems.[/color]

                    Hi,

                    I don't understand how strncpy() can cause problems. I wrote a small test
                    app below and as far as I can tell the extra \0 null terminators don't
                    effect how the c code works.

                    It seems as though c stops looking past the first \0 it finds in the
                    string. Also it doesn't change strlen() or other functions I tested.

                    #include <stdio.h>

                    char teststring[40] = "test string now";
                    char teststring1[40];
                    char teststring2[20];

                    int main() {
                    printf("teststr ing = %s", teststring);
                    strcpy(teststri ng1, teststring);
                    printf("\ntests tring1 = %s", teststring1);

                    strncpy(teststr ing, "I changed string value\0", sizeof teststring);
                    strcpy(teststri ng1, "I changed string value\0");
                    strcpy(teststri ng2, "test\0now" );

                    printf("\n\ntes tstring now = %s", teststring);
                    printf("\n\ntes tstring1 now = %s", teststring1);
                    printf("\n\ntes tstring2 now = %s", teststring2);

                    printf("\n\ntes tstring size = %d", strlen(teststri ng));
                    printf("\n\ntes tstring1 size = %d", strlen(teststri ng1));

                    return 0;
                    }


                    Kind Regards,
                    Anthony Irwin

                    Comment

                    • Rich Webb

                      #11
                      Re: C and strings

                      On Thu, 11 Aug 2005 01:20:02 GMT, Keith Thompson <kst-u@mib.org> wrote:
                      [color=blue]
                      >Second, strncpy() isn't as superior to strcpy() as you might think.
                      >It does let you limit the number of bytes to copy, but its behavior is
                      >questionable in many cases. For example, if you do
                      > strncpy(s, "hello", 5);
                      >it will copy exactly 5 characters to s; it will *not* copy the
                      >terminating '\0' character. On the other hand, if you do[/color]
                      [snip...snip...][color=blue]
                      >strcpy() is safe *if* you first confirm that the target is big enough
                      >to hold the string being copied. strncpy() can avoid array overflow
                      >bugs, but at the expense of introducing other problems.[/color]

                      There's always the option of
                      strncpy(s, "hello", S_BUF_LEN)[S_BUF_LEN - 1] = '\0';

                      Ugly, but ...

                      --
                      Rich Webb Norfolk, VA

                      Comment

                      • pete

                        #12
                        Re: C and strings

                        Anthony Irwin wrote:[color=blue]
                        >
                        > On Thu, 11 Aug 2005 01:20:02 +0000, Keith Thompson wrote:[/color]
                        [color=blue][color=green]
                        > > wastefully writing 495 '\0' characters when one would have
                        > > been sufficient.[/color][/color]
                        [color=blue]
                        > as far as I can tell the extra \0 null terminators don't
                        > effect how the c code works.[/color]

                        That's right.
                        Keith Thompson's objection was to the wasted effort in writing them.

                        --
                        pete

                        Comment

                        • Keith Thompson

                          #13
                          Re: C and strings

                          Anthony Irwin <nospam@example .com> writes:[color=blue]
                          > On Thu, 11 Aug 2005 01:20:02 +0000, Keith Thompson wrote:
                          >
                          > <snip>[color=green]
                          >> terminating '\0' character. On the other hand, if you do
                          >> strncpy(s, "hello", 500);
                          >> (assuming that s is big enough) it will pad the target with null
                          >> characters, wastefully writing 495 '\0' characters when one would have
                          >> been sufficient.
                          >>
                          >> The strncpy() function, despite the name, doesn't consistently work
                          >> with C strings; it works with a specific data structure that's rarely
                          >> used these days, a '\0'-padded character array in which the trailing
                          >> '\0' is optional if the actual data fills the array. (This was used
                          >> by early versions of Unix to store file names, back when they were
                          >> limited to 14 characters.)
                          >>
                          >> strcpy() is safe *if* you first confirm that the target is big enough
                          >> to hold the string being copied. strncpy() can avoid array overflow
                          >> bugs, but at the expense of introducing other problems.[/color]
                          >
                          > Hi,
                          >
                          > I don't understand how strncpy() can cause problems. I wrote a small test
                          > app below and as far as I can tell the extra \0 null terminators don't
                          > effect how the c code works.
                          >
                          > It seems as though c stops looking past the first \0 it finds in the
                          > string. Also it doesn't change strlen() or other functions I tested.
                          >[/color]
                          [sample program snipped]

                          The problem with the extra '\0' bytes, as pete wrote in another
                          followup, is merely the wasted time spent writing them.

                          That's not a serious flaw unless the third argument is very large.
                          The more serious problem is one that your test program doesn't
                          illustrate. Consider this:

                          #include <stdio.h>
                          #include <string.h>
                          int main(void)
                          {
                          char buf[10] = "0123456789 ";
                          strncpy(buf, "hello", 5);
                          printf("buf = \"%s\"\n", buf);
                          return 0;
                          }

                          The output is:

                          buf = "hello56789 "

                          If I had declared buf as an array of 5 characters, and used the 3rd
                          argument to strncpy() to avoid overflowing it, I would have been left
                          with no '\0' in the array. The printf() call most likely would have
                          kept printing characters until it happened to run into a '\0'
                          somewhere else (strictly speaking, it would invoke undefined behavior
                          as soon as it ran off the end of the array).

                          strcpy() is dangerous unless you first check that the target string is
                          big enough. strncpy() is dangerous unless you understand exactly how
                          it works -- and if you *think* you know how it works, you should
                          probably read the documentation one more time just to make sure.

                          It's easy to assume that strncpy is to strcpy as snprintf is to
                          sprintf, but it's not. snprintf takes an extra argument that
                          specifies the maximum number of characters to write to the target, but
                          it always writes the trailing '\0'.

                          --
                          Keith Thompson (The_Other_Keit h) kst-u@mib.org <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.

                          Comment

                          • bwaichu@yahoo.com

                            #14
                            Re: C and strings


                            Keith Thompson wrote:[color=blue]
                            > strcpy() is dangerous unless you first check that the target string is
                            > big enough. strncpy() is dangerous unless you understand exactly how
                            > it works -- and if you *think* you know how it works, you should
                            > probably read the documentation one more time just to make sure.[/color]

                            There is a very good paper on this topic:



                            Brian

                            P.S. Keith, I quoted you.

                            Comment

                            • Malcolm

                              #15
                              Re: C and strings


                              "Anthony Irwin" <nospam@example .com> wrote[color=blue]
                              >
                              > I am new to c and am having trouble with strings can anyone give me some
                              > quick pointers or point me to a good c strings tutorial?
                              >[/color]
                              C strings are often confusing for people who come from another programming
                              language.

                              C is so low-level that effectively there is no such thing as a string type.
                              "strings" are sequences of chars terminated by a NUL (ASCII zero).

                              The only support C gives for strings in the strict sense of the word is that
                              entering a string literal
                              char *str = "Fred Bloggs";
                              creates the sequence 'F' 'r' 'e' 'd' ' ' 'B' 'l' 'o' 'g' 'g' 's' '\0'
                              in memory.

                              Also there are library functions which operate on such sequences.

                              The best tutorial on strings is to try to implement strlen(), strcpy() etc
                              yourself. call them my-strlen() etc to avoid namespace problems.

                              [color=blue]
                              > Below is a
                              > program I am working on.
                              >
                              > Kind Regards,
                              > Anthony Irwin
                              >
                              > #include <stdio.h>
                              >
                              > char teststring[40] = "test string now";
                              > char teststring1[40];
                              >
                              > int main() {
                              > printf("teststr ing = %s", teststring);
                              > strcpy(teststri ng1, teststring);
                              > printf("\ntests tring1 = %s", teststring1);
                              >
                              > /* How can I assign a new value to teststring say
                              > * the value "I changed string text" */
                              >
                              > printf("\n\nI changed teststring to = %s\n", teststring);
                              >
                              > return 0;
                              > }[/color]


                              Comment

                              Working...