Problem with character string loop and strlen()

N

No Such Luck

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

Dave Vandervies

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
 
P

Peter Nilsson

No said:
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);
}
 
A

Al Bowers

No said:
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');
}
 
C

CBFalconer

No said:
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 */
}
 
J

Joe Wright

No said:
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
 
C

CBFalconer

Joe said:
.... 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.
 
P

Peter Nilsson

CBFalconer said:
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.
 
O

Old Wolf

No said:
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 */
}
 
J

Joe Wright

Old said:
No said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,999
Latest member
MakersCBDGummiesReview

Latest Threads

Top