Reputation: 59
I'm trying to solve a piece of code a friend sent me. He's practicing pointers and is trying to reverse a string using them.
It should be a pretty simple task, but there's just a gap in my knowledge here. I've been able to successfully create a for loops which iterates through the string properly using i
and j
as control variables. I've been able to print out the characters as well, which need to be swapped.
The only problem is that commented line of code in the for loop. It's supposed to be swapping the two values, but is throwing an error, and I don't get why.
#include <stdio.h>
int length(char *p);
void reverse(char *);
int main() {
char *p = "Computer";
reverse(p);
}
int length(char *p) {
int i;
for (i = 0; *(p + i) != '\0'; i++);
return i;
}
void reverse(char *p) {
int l, i;
char t;
for (l = 0; *(p + l) != '\0'; l++);
int len = l;
int temp;
for (i = 0; i < l; i++, l--) {
t = *(p + i);
printf("i-th element - %c\n", t);
printf("j-th element - %c\n", *(p + len - 1 - i));
*(p + i) = *(p + len - 1 - i); // crash
}
puts(p);
}
I'm not even sure it's possible to swap them this way. I would have gone with the t = p[i]; p[i] = p[i + 1]...
approach. If anyone can correct and explain this and the pointer related drama, that would be great.
Upvotes: 1
Views: 430
Reputation: 332
If you want to save the string for later vice printing it directly to stdout
, you can do this:
char * reverse(char * I){
int i,l;
char * O;
l=strlen(I);
O=malloc(l+1);
for(i=1;i<=l;i++)O[i-1]=I[l-i];
O[l]='\0';
return O;
}
int main(){
char * p=reverse("Computer");
printf("%s",p);
free(p);
}
Upvotes: 0
Reputation: 106
Using pointes requires some care otherwise you'll get "Segmentation fault" everywhere. But let's do this. A technique to reverse the string I use, is first position one ponter to the beginning of string, and another pointer to the end of string; and promote the swap while they reach the middle of string (this way I cut the processing to a half) check this code
/* reverses a string
* !!! this function modifies input string !!!
*/
char *reverse(char *s)
{
char *h, *t, c; /* h)ead, t)ail and a temporary c */
int len = 0;
/* positioning the pointers at beginning and end of string s */
len = length(s);
h = (char*)&s[0];
t = (char*)&s[len - 1];
for (int i = 0; i < (len / 2); i++)
{
/* swap chars */
c = *h;
*h = *t;
*t = c;
/* increase h pointer, decrease t pointer */
h++;
t--;
}
return s;
}
Pure pointers... in anyform when swapping the *h and *t you can't get away from a temporary storage ( c );
Be aware the input string needs to be declared as char name[] otherwhise sigsegv follows you!
Upvotes: 0
Reputation: 311038
For starters you may not change a string literal
char *p = "Computer";
any attempt to change a string literal result in undefined behavior.
So instead of the pointer to a string literal declare a character array like
char s[] = "Computer";
Moreover your function reverse
does not use the function length
and in fact does not reverse a string.
This loop
for (i = 0; i < l; i++, l--) {
uses two auxiliary variables as indices.
The function reverse
shall output nothing. What it shall do is one thing to reverse the passed string. It is the caller of the function that decides whether to output the reversed string or to use it for other purposes.
The functions length
and reverse
can be declared and defined using only pointers the following way
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
and
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
The function reverse can be called like
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
Here is a demonstrative program.
#include <stdio.h>
size_t length( const char *s )
{
const char *p = s;
while ( *p ) ++p;
return p - s;
}
char * reverse( char *s )
{
if ( *s )
{
for ( char *p = s, *q = s + length( s ); p < --q; ++p )
{
char c = *p;
*p = *q;
*q = c;
}
}
return s;
}
int main( void )
{
char s[] = "Computer";
puts( s );
puts( reverse( s ) );
}
Its output is
Computer
retupmoC
As you can see in the both functions neither variable used as an index is present. The functions use only pointers.
Upvotes: 1
Reputation: 75062
Firstly, you must not try to modify string literals.
You should use an (modifiable) array:
char p[] = "Computer";
instead of
char *p = "Computer";
Secondly, you will need
*(p + len - 1 - i) = t;
after
*(p + i) = *(p + len - 1 - i);
to complete the swapping.
Upvotes: 4