Problem with character string loop and strlen()

Discussion in 'C Programming' started by No Such Luck, Jul 7, 2005.

  1. No Such Luck

    No Such Luck Guest

    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.
     
    No Such Luck, Jul 7, 2005
    #1
    1. Advertising

  2. In article <>,
    No Such Luck <> wrote:
    >
    >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"


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


    >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?


    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
    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
     
    Dave Vandervies, Jul 8, 2005
    #2
    1. Advertising

  3. No Such Luck wrote:
    > 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--)


    Why do you want to loop if the string is empty?

    > {
    > /* do something */
    > }
    >
    > return 1;
    > }
    >
    > Here is my problem. strlen() returns an unsigned value,


    More precisely it returns the best type for indexing, namely, size_t.

    > 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?


    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);
    }

    --
    Peter
     
    Peter Nilsson, Jul 8, 2005
    #3
  4. No Such Luck

    Al Bowers Guest

    No Such Luck wrote:
    > 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?
    >


    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: (remove the x to send email)
    http://www.geocities.com/abowers822/
     
    Al Bowers, Jul 8, 2005
    #4
  5. No Such Luck

    CBFalconer Guest

    No Such Luck wrote:
    >
    > 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?


    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
     
    CBFalconer, Jul 8, 2005
    #5
  6. No Such Luck

    Joe Wright Guest

    No Such Luck wrote:
    > 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.
    >


    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 ---
     
    Joe Wright, Jul 9, 2005
    #6
  7. No Such Luck

    CBFalconer Guest

    Joe Wright wrote:
    >

    .... snip ...
    >
    > 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


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

    --
    "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, Jul 9, 2005
    #7
  8. CBFalconer wrote:
    > Joe Wright wrote:
    > >

    > ... snip ...
    > >
    > > 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

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


    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
     
    Peter Nilsson, Jul 9, 2005
    #8
  9. No Such Luck

    Old Wolf Guest

    No Such Luck wrote:
    > 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.


    unsigned int i;
    for (i = strlen(string); i--; )
    {
    /* do something */
    }
     
    Old Wolf, Jul 9, 2005
    #9
  10. No Such Luck

    Joe Wright Guest

    Old Wolf wrote:
    > No Such Luck wrote:
    >
    >>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.

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

    I like that.

    --
    Joe Wright
    "Everything should be made as simple as possible, but not simpler."
    --- Albert Einstein ---
     
    Joe Wright, Jul 10, 2005
    #10
    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. apropo

    strlen in a for loop with malloc-ed char*

    apropo, Oct 19, 2004, in forum: C Programming
    Replies:
    33
    Views:
    1,242
    Michael Mair
    Nov 20, 2004
  2. lasek

    strlen + terminating null character

    lasek, Mar 25, 2005, in forum: C Programming
    Replies:
    5
    Views:
    345
    Keith Thompson
    Mar 26, 2005
  3. lasek
    Replies:
    9
    Views:
    2,468
    Rufus V. Smith
    May 20, 2005
  4. karthikbalaguru

    For loop and strlen

    karthikbalaguru, Sep 20, 2009, in forum: C Programming
    Replies:
    8
    Views:
    1,284
    Herbert Rosenau
    Sep 26, 2009
  5. Isaac Won
    Replies:
    9
    Views:
    387
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page