Problem with character string loop and strlen()

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • No Such Luck

    Problem with character string loop and strlen()


    I have a function which requires me to loop from the end of a string to
    the beginning on a char by char basis:

    int foo (char string[])
    {
    unsigned int i;

    for(i = strlen(string); i >= 0; i--)
    {
    /* do something */
    }

    return 1;
    }

    Here is my problem. strlen() returns an unsigned value, so if I use a
    signed loop variable, I receive a warning: "'<' : signed/unsigned
    mismatch"

    However, if I use a unsigned loop variable to compare against the
    correct return type of strlen(), the loop never ends. The value of 'i'
    turns from 0 to the highest unsigned value possible.

    Any ideas on how to solve this problem, and not receive the warning?

    Thanks,

    P.S. Traversing the string forwards is not an option.

  • Peter Nilsson

    #2
    Re: Problem with character string loop and strlen()

    No Such Luck wrote:[color=blue]
    > I have a function which requires me to loop from the end of a string to
    > the beginning on a char by char basis:
    >
    > int foo (char string[])
    > {
    > unsigned int i;
    >
    > for(i = strlen(string); i >= 0; i--)[/color]

    Why do you want to loop if the string is empty?
    [color=blue]
    > {
    > /* do something */
    > }
    >
    > return 1;
    > }
    >
    > Here is my problem. strlen() returns an unsigned value,[/color]

    More precisely it returns the best type for indexing, namely, size_t.
    [color=blue]
    > so if I use a signed loop variable, I receive a warning: "'<' :
    > signed/unsigned mismatch"
    >
    > However, if I use a unsigned loop variable to compare against the
    > correct return type of strlen(), the loop never ends. The value of 'i'
    > turns from 0 to the highest unsigned value possible.
    >
    > Any ideas on how to solve this problem, and not receive the warning?[/color]

    A compiler can issue a warning for any reason it likes, so no one
    can guarantee you won't get a warning, but the following may be what
    you're after...

    size_t i = strlen(string);
    while (i--)
    {
    putchar(string[i]);
    }

    --
    Peter

    Comment

    • Dave Vandervies

      #3
      Re: Problem with character string loop and strlen()

      In article <1120776202.508 569.132730@z14g 2000cwz.googleg roups.com>,
      No Such Luck <no_suchluck@ho tmail.com> wrote:[color=blue]
      >
      >I have a function which requires me to loop from the end of a string to
      >the beginning on a char by char basis:
      >
      >int foo (char string[])
      >{
      > unsigned int i;
      >
      > for(i = strlen(string); i >= 0; i--)
      > {
      > /* do something */
      > }
      >
      > return 1;
      >}
      >
      >Here is my problem. strlen() returns an unsigned value, so if I use a
      >signed loop variable, I receive a warning: "'<' : signed/unsigned
      >mismatch"[/color]

      Are you sure? I don't see any way for the code you posted to produce
      a warning anything like that.

      [color=blue]
      >However, if I use a unsigned loop variable to compare against the
      >correct return type of strlen(), the loop never ends. The value of 'i'
      >turns from 0 to the highest unsigned value possible.
      >
      >Any ideas on how to solve this problem, and not receive the warning?[/color]

      Don't compare signed values with unsigned values.

      Or (sometimes better, depending heavily on philosophical and aesthetic
      opinions) just document that the code produces a warning and why the
      warning should be ignored.


      dave

      --
      Dave Vandervies dj3vande@csclub .uwaterloo.ca
      More proof that the surefire way to discover the answer to your question
      is to ask it in a public forum.
      --Peter Ammon in comp.lang.c

      Comment

      • Al Bowers

        #4
        Re: Problem with character string loop and strlen()



        No Such Luck wrote:[color=blue]
        > I have a function which requires me to loop from the end of a string to
        > the beginning on a char by char basis:
        >
        > int foo (char string[])
        > {
        > unsigned int i;
        >
        > for(i = strlen(string); i >= 0; i--)
        > {
        > /* do something */
        > }
        >
        > return 1;
        > }
        >
        > Here is my problem. strlen() returns an unsigned value, so if I use a
        > signed loop variable, I receive a warning: "'<' : signed/unsigned
        > mismatch"
        >
        > However, if I use a unsigned loop variable to compare against the
        > correct return type of strlen(), the loop never ends. The value of 'i'
        > turns from 0 to the highest unsigned value possible.
        >
        > Any ideas on how to solve this problem, and not receive the warning?
        >[/color]

        Yes. There is no need to do the test i >= 0 when the test
        can easily be made i > 0. This would solve the problem.
        Example:

        #include <string.h>
        #include <stdio.n>

        void foo (const char string[])
        {
        size_t i;

        for(i = strlen(string); i > 0; i--)
        putchar(string[i-1]);
        putchar('\n');
        }

        --
        Al Bowers
        Tampa, Fl USA
        mailto: xabowers@myrapi dsys.com (remove the x to send email)
        Latest news coverage, email, free stock quotes, live scores and video are just the beginning. Discover more every day at Yahoo!


        Comment

        • CBFalconer

          #5
          Re: Problem with character string loop and strlen()

          No Such Luck wrote:[color=blue]
          >
          > I have a function which requires me to loop from the end of a string to
          > the beginning on a char by char basis:
          >
          > int foo (char string[])
          > {
          > unsigned int i;
          >
          > for(i = strlen(string); i >= 0; i--)
          > {
          > /* do something */
          > }
          > return 1;
          > }
          >
          > Here is my problem. strlen() returns an unsigned value, so if I use a
          > signed loop variable, I receive a warning: "'<' : signed/unsigned
          > mismatch"
          >
          > However, if I use a unsigned loop variable to compare against the
          > correct return type of strlen(), the loop never ends. The value of 'i'
          > turns from 0 to the highest unsigned value possible.
          >
          > Any ideas on how to solve this problem, and not receive the warning?[/color]

          ix = 1 + strlen(string);
          while (ix--) {
          /* do something. string[ix] is last unused char */
          }

          --
          "They that can give up essential liberty to obtain a little
          temporary safety deserve neither liberty nor safety."
          -- B. Franklin, 1759


          Comment

          • Joe Wright

            #6
            Re: Problem with character string loop and strlen()

            No Such Luck wrote:[color=blue]
            > I have a function which requires me to loop from the end of a string to
            > the beginning on a char by char basis:
            >
            > int foo (char string[])
            > {
            > unsigned int i;
            >
            > for(i = strlen(string); i >= 0; i--)
            > {
            > /* do something */
            > }
            >
            > return 1;
            > }
            >
            > Here is my problem. strlen() returns an unsigned value, so if I use a
            > signed loop variable, I receive a warning: "'<' : signed/unsigned
            > mismatch"
            >
            > However, if I use a unsigned loop variable to compare against the
            > correct return type of strlen(), the loop never ends. The value of 'i'
            > turns from 0 to the highest unsigned value possible.
            >
            > Any ideas on how to solve this problem, and not receive the warning?
            >
            > Thanks,
            >
            > P.S. Traversing the string forwards is not an option.
            >[/color]

            Suppose ..
            char string[] = "Hello";

            The constant array has length 6.
            strlen(string) is 5.
            The five subscripts are 0..4

            for (i = strlen(string); i > 0; --i)

            will loop for i == 5..1

            treat the individual characters with string[i-1]

            You can define
            int i;
            such that i is signed. Regard..

            for (i = strlen(string)-1; i >= 0; --i)

            will loop for i == 4..0
            --
            Joe Wright
            "Everything should be made as simple as possible, but not simpler."
            --- Albert Einstein ---

            Comment

            • CBFalconer

              #7
              Re: Problem with character string loop and strlen()

              Joe Wright wrote:[color=blue]
              >[/color]
              .... snip ...[color=blue]
              >
              > You can define
              > int i;
              > such that i is signed. Regard..
              >
              > for (i = strlen(string)-1; i >= 0; --i)
              >
              > will loop for i == 4..0[/color]

              You will get a nasty surprise when strlen(string) is zero.

              --
              "If you want to post a followup via groups.google.c om, 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


              Comment

              • Peter Nilsson

                #8
                Re: Problem with character string loop and strlen()

                CBFalconer wrote:[color=blue]
                > Joe Wright wrote:[color=green]
                > >[/color]
                > ... snip ...[color=green]
                > >
                > > You can define
                > > int i;
                > > such that i is signed. Regard..
                > >
                > > for (i = strlen(string)-1; i >= 0; --i)
                > >
                > > will loop for i == 4..0[/color]
                >
                > You will get a nasty surprise when strlen(string) is zero.[/color]

                Unfortunately, chances are he won't. On most modern systems
                where the conversion from unsigned to signed is simply a
                no-op or truncation in twos complement representation, programs
                like...

                #include <stdio.h>

                int main(void)
                {
                int i = 0u - 1;
                printf("%d\n", i);
                return 0;
                }

                ....will output -1 as 'expected'.

                The issue CBFalconer is hinting at is the fact that size_t is
                unsigned and often unsigned int or unsigned long. Because of
                promotion, the subtraction of 1 from such unsigned integers
                will yield UINT_MAX or ULONG_MAX where both are likely to be
                outside the range of int. If so, these values will then be
                converted in an implementation defined way back into int in
                the assignment to i. [Under C99, an implementation defined
                signal can even be raised.] There is no guarantee that i will
                get the value -1 on every conforming implementation.

                --
                Peter

                Comment

                • Old Wolf

                  #9
                  Re: Problem with character string loop and strlen()

                  No Such Luck wrote:[color=blue]
                  > I have a function which requires me to loop from the end of a string to
                  > the beginning on a char by char basis:
                  >
                  > int foo (char string[])
                  > {
                  > unsigned int i;
                  >
                  > for(i = strlen(string); i >= 0; i--)
                  > {
                  > /* do something */
                  > }
                  >
                  > return 1;
                  > }
                  >
                  > if I use a unsigned loop variable to compare against the
                  > correct return type of strlen(), the loop never ends. The value
                  > of 'i' turns from 0 to the highest unsigned value possible.[/color]

                  unsigned int i;
                  for (i = strlen(string); i--; )
                  {
                  /* do something */
                  }

                  Comment

                  • Joe Wright

                    #10
                    Re: Problem with character string loop and strlen()

                    Old Wolf wrote:[color=blue]
                    > No Such Luck wrote:
                    >[color=green]
                    >>I have a function which requires me to loop from the end of a string to
                    >>the beginning on a char by char basis:
                    >>
                    >>int foo (char string[])
                    >>{
                    >> unsigned int i;
                    >>
                    >> for(i = strlen(string); i >= 0; i--)
                    >> {
                    >> /* do something */
                    >> }
                    >>
                    >> return 1;
                    >>}
                    >>
                    >>if I use a unsigned loop variable to compare against the
                    >>correct return type of strlen(), the loop never ends. The value
                    >>of 'i' turns from 0 to the highest unsigned value possible.[/color]
                    >
                    >
                    > unsigned int i;
                    > for (i = strlen(string); i--; )
                    > {
                    > /* do something */
                    > }
                    >[/color]
                    I like that.

                    --
                    Joe Wright
                    "Everything should be made as simple as possible, but not simpler."
                    --- Albert Einstein ---

                    Comment

                    Working...