By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,903 Members | 1,670 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,903 IT Pros & Developers. It's quick & easy.

Reverse a string in place

P: n/a
Thanks for the additional comments.

Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.

#include<stdio.h>

#define SWAP(a,b) { char x; x=(a); (a)=(b); (b)=x; }

void reverse();

main(int argc, char**argv)
{
if(argc>1) {
reverse(argv[1]);
printf("%s\n", argv[1]);
} else
printf("Unspecified error\n");
}

void reverse(char *s)
{
static int n=-1;
if(n==-1)
n=strlen(s)-1;
SWAP(*s, s[n]);
if((n-=2)>=0)
reverse(s+1);
else
n=-1; /* make sure function is reentrant */
}
Dec 6 '07 #1
Share this Question
Share on Google+
15 Replies


P: n/a
On Dec 6, 3:15 pm, raj...@thisisnotmyrealemail.com wrote:
Thanks for the additional comments.

Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.
void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */

while (string end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}

Dec 6 '07 #2

P: n/a
Oops... pardon my typo...

On Dec 6, 3:28 pm, Lew Pitcher <lpitc...@teksavvy.comwrote:
On Dec 6, 3:15 pm, raj...@thisisnotmyrealemail.com wrote:
Thanks for the additional comments.
Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */

while (string end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}

}

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
Dec 6 '07 #3

P: n/a
Lew Pitcher wrote:
On Dec 6, 3:15 pm, raj...@thisisnotmyrealemail.com wrote:
Thanks for the additional comments.

Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */

while (string end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
Uhh yes! I should have said clearly that it's Exercise 4.13 - write a
**recursive** version of reverse(s).
Dec 6 '07 #4

P: n/a
ra****@thisisnotmyrealemail.com wrote:
) Uhh yes! I should have said clearly that it's Exercise 4.13 - write a
) **recursive** version of reverse(s).

That's silly. Reversing a string is clearly an iterative operation.
However, any iteration can be easily transformed into a tail recursion.

Note, also, that it is perfectly valid to have two functions.
One that recurses, and one that makes the initial call to the other.

Anyways, Here's a stab at a very inefficient and silly solution, using
a single function:

void reverse(char *string)
{
size_t len = strlen(string);
if (len 1) {
char tmp = string[len-1];
string[len-1] = 0;
reverse(string + 1);
string[len-1] = string[0];
string[0] = tmp;
}
}
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Dec 6 '07 #5

P: n/a
ra****@thisisnotmyrealemail.com writes:
Thanks for the additional comments.

Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.

#include<stdio.h>

#define SWAP(a,b) { char x; x=(a); (a)=(b); (b)=x; }
I'd either just write this code out, or I'd make this a function. If
I really needed it to be a macro, I'd use the "do {} while (0)" idiom
so as to get syntactic unit that can be followed by a ; and remain a
single statement.
void reverse();
This is not a prototype for reverse, just a declaration. Tell the
full story by writing:

void reverse(char *s);
main(int argc, char**argv)
int main is better and required in C99.
{
if(argc>1) {
reverse(argv[1]);
printf("%s\n", argv[1]);
} else
printf("Unspecified error\n");
}

void reverse(char *s)
{
static int n=-1;
if(n==-1)
n=strlen(s)-1;
SWAP(*s, s[n]);
if((n-=2)>=0)
reverse(s+1);
else
n=-1; /* make sure function is reentrant */
}
Spaces have come right down in price recently after the discovery of
the Peruvian space deposits. Help yourself to a few more.

Reverse is not a natural candidate for recursion (even in functional
languages a little care is needed to stop it being very inefficient)
but in C we have some extra options because we can modify the string.
I'd write it like this:

void rev(char *start, char *end)
{
if (start + 1 >= end)
return;
else {
char t = end[-1];
end[-1] = *start;
*start = t;
rev(start + 1, end - 1);
}
}

void reverse(char *s)
{
rev(s, strchr(s, 0));
}

--
Ben.
Dec 6 '07 #6

P: n/a
Lew Pitcher wrote:
>
Oops... pardon my typo...

On Dec 6, 3:28 pm, Lew Pitcher <lpitc...@teksavvy.comwrote:
On Dec 6, 3:15 pm, raj...@thisisnotmyrealemail.com wrote:
Thanks for the additional comments.
Here is a solution to an exercise I had problems with. I still don't
think it's really what's wanted as it uses a "state variable" n - but
I can't see how to do it without this (or changing the function to
take an extra argument). Thanks for any hints.
void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */

while (string end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}

}

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end); --end;
/* end points to last character in string */
Unless the string is (""),
in which case (end) is undefined.
while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
--
pete
Dec 7 '07 #7

P: n/a
pete wrote:
Lew Pitcher wrote:
.... snip ...
>
>void reverse(char *string) {
char *end;
for (end = string; *end ; ++end); --end;
/* end points to last character in string */

Unless the string is (""), in which case (end) is undefined.
> while (string < end) {
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
So try:

void reverse(char *string) {
char *end, temp;

for (end = string; *end; end++) continue;
/* leaving *end == 0 */
while (string < end) {
temp = *string;
*string++ = *(--end);
*end = temp;
)
} /* reverse, untested */

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

--
Posted via a free Usenet account from http://www.teranews.com

Dec 8 '07 #8

P: n/a
RoS
In data Fri, 14 Dec 2007 12:56:08 -0500, pete scrisse:
what is the difference of the below 2 routines?
>This version of reverse, does nothing:

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end);
if (*end) --end; else return;
/* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
This version of reverse, reverses a string:

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end);
if (*string) --end; else return;
/* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}

If you can't see that, then you can't read code anymore.

Nobody else is seeing that code the way that you do.
Dec 14 '07 #9

P: n/a
RoS
In data Fri, 14 Dec 2007 20:53:42 +0100, RoS scrisse:
>In data Fri, 14 Dec 2007 12:56:08 -0500, pete scrisse:
what is the difference of the below 2 routines?
yes i have seen it ...

void reverse(char *aa)
{char *a=aa, *b, t;
if(a==0||*a==0) return;
for( ; *a; ++a);
for(--a, b=aa; b<a; ++b, --a)
{t=*b; *b=*a; *a=t;}
}

this is my version whithout compile it nor debug it
>>This version of reverse, does nothing:

void reverse(char *string)
but str* were not implementation reserved?
>>{
char *end;

for (end = string; *end ; ++end);
if (*end) --end; else return;
when this case "*end!=0" is verified here? (never)

> /* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
This version of reverse, reverses a string:

void reverse(char *string)
{
char *end;

for (end = string; *end ; ++end);
if (*string) --end; else return;
/* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}

If you can't see that, then you can't read code anymore.

Nobody else is seeing that code the way that you do.
Dec 14 '07 #10

P: n/a
RoS wrote:
>
In data Fri, 14 Dec 2007 20:53:42 +0100, RoS scrisse:
In data Fri, 14 Dec 2007 12:56:08 -0500, pete scrisse:
what is the difference of the below 2 routines?

yes i have seen it ...

void reverse(char *aa)
{char *a=aa, *b, t;
if(a==0||*a==0) return;
for( ; *a; ++a);
for(--a, b=aa; b<a; ++b, --a)
{t=*b; *b=*a; *a=t;}
}

this is my version whithout compile it nor debug it
OK
>This version of reverse, does nothing:

void reverse(char *string)

but str* were not implementation reserved?
No.
The rules are more complicated than that.

N869
7.26.10 General utilities <stdlib.h>
[#1] Function names that begin with str and a lowercase
letter (possibly followed by any combination of digits,
letters, and underscore) may be added to the declarations in
the <stdlib.hheader.

7.26.11 String handling <string.h>
[#1] Function names that begin with str, mem, or wcs and a
lowercase letter (possibly followed by any combination of
digits, letters, and underscore) may be added to the
declarations in the <string.hheader.

>{
char *end;

for (end = string; *end ; ++end);
if (*end) --end; else return;

when this case "*end!=0" is verified here? (never)
You are correct!
/* end points to last character in string */

while (string < end)
{
char temp;

temp = *string;
*string++ = *end;
*end-- = temp;
}
}
--
pete
Dec 14 '07 #11

P: n/a
CBFalconer wrote:
However, if *string is 0 the else
clause arises, and the function returns without doing anything.
That's what it's supposed to do.

No action is required to reverse a zero length string.

If (*string) is 0,
then you are reversing a zero length string.

void reverse(char *string)
{
char *end;

for (end = string ; *end ; ++end);
if (*string) --end; else return;

--
pete
Dec 15 '07 #12

P: n/a
ozbear wrote:
CBFalconer <cb********@yahoo.comwrote:
.... snip ...
>>
If the string is non-empty the test (*string) is true, --end is
executed, and end no longer points to a zero, but to the last
character in the string.

I didn't miss that point, but it isn't what Lew originally wrote,
since he was testing *end, not *string, for the early return
in the case of an empty string (please look at his original
"correction" to cater for empty strings). I corrected it.

Do you dispute that:
1) The original addition of testing *end was incorrect.
2) My modification corrects that flaw.
3) Lew's original correction for empty strings will cause the
code to not reverse -any- string (just not have UB for
empty ones).

If you disagree with any of (1), (2) or (3), please tell me why.
If you don't, then I don't understand what you were objecting to
in the first place.
Here is the original quote. string is the input parameter, and end
is local to the function.
>>>>>> for (end = string ; *end ; ++end);
>> if (*string) --end; else return;
> ^^^^^^
The above code exits for an empty string input. Only. I was
objecting to the misinterpretation of the code by others.

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

--
Posted via a free Usenet account from http://www.teranews.com

Dec 15 '07 #13

P: n/a
pete wrote:
CBFalconer wrote:
>However, if *string is 0 the else
clause arises, and the function returns without doing anything.

That's what it's supposed to do.
That's what I said, and you objected to.

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

--
Posted via a free Usenet account from http://www.teranews.com

Dec 15 '07 #14

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Here is the original quote. string is the input parameter, and end
is local to the function.
>>>>>>> for (end = string ; *end ; ++end);
>>> if (*string) --end; else return;
>> ^^^^^^

The above code exits for an empty string input. Only. I was
objecting to the misinterpretation of the code by others.
Who misinterpreted it? You certainly seemed to, since when the
correction (from *end to *string) was suggested by ozbear, your reply
started with the word "No". It was:

| ozbear wrote:
| Shouldn't that be:
| >
| if (*string) --end; else return;
| ^^^^^^
|
| No, because that clause detects the original supply of string as
| "", when end was never advanced, and exits early.

What you say after "No" suggests you know what it does, but I just
can't see why you start "No, ...". It made me think you had missed
the point of the correction. If you had replied "Yes, that clause..."
then I think this whole sub-thread would never have happened.

--
Ben.
Dec 15 '07 #15

P: n/a
CBFalconer wrote:
>
pete wrote:
CBFalconer wrote:
However, if *string is 0 the else
clause arises, and the function returns without doing anything.
That's what it's supposed to do.

That's what I said, and you objected to.
I like ozbear's correction to Lew Pitcher's code.
If you do too, then we're all agreed.

--
pete
Dec 15 '07 #16

This discussion thread is closed

Replies have been disabled for this discussion.