Velocity Reviews > Pointer arithmetic question.

Pointer arithmetic question.

Guest
Posts: n/a

 10-30-2012
Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:

char *strcpy(char * s, char * t)
{

char x;
while(x=*s)
s++;

while((*s++=*t++))
;

return ;
}
int main(void)
{
char message[100]="string1";
char * message2="string2";
strcpy(message, message2);
printf("%s", message);
return 0;

}

And here's a version that doesn't work:
char *strcpy(char * s, char * t)
{

while(*s++)
;

while((*s++=*t++))
;

return ;
}
int main(void)
{
char message[100]="string1";
char * message2="string2";
strcpy(message, message2);
printf("%s", message);
return 0;

}
It seems that for some reason the while(*s++) is 0 so it doesn't increment. Why? What am I missing here?

tom st denis
Guest
Posts: n/a

 10-30-2012
On Oct 30, 1:33*pm, Adrian Sch <(E-Mail Removed)> wrote:
> Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:
>
> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;
>
> while((*s++=*t++))
> ;
>
> return ;}
>
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
>
> And here's a version that doesn't work:
> char *strcpy(char * s, char * t)
> {
>
> while(*s++)
> ;

Ask your self, where does "s" point now. (hint: compare the value of
's' in this version against the other via printf("%p\n", s)).

> while((*s++=*t++))
> ;
>
> return ;}
>
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
>
> It seems that for some reason the while(*s++) is 0 so it doesn't increment. Why? What am I missing here?

Once you figure out where 's' points to after the while(*s++) loop
you'll figure out the bug in the 2nd copy.

Tom

Greg Martin
Guest
Posts: n/a

 10-30-2012
On 12-10-30 10:33 AM, Adrian Sch wrote:
> Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:
>
> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;
>
> while((*s++=*t++))
> ;
>
> return ;
> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
>
> And here's a version that doesn't work:
> char *strcpy(char * s, char * t)
> {
>
> while(*s++)
> ;
>
> while((*s++=*t++))
> ;
>
> return ;
> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
> It seems that for some reason the while(*s++) is 0 so it doesn't increment. Why? What am I missing here?
>

I made a couple of changes to your program. Some to make my compiler
happy, some for readability and one to make the program work. The
pre-increment will return the value after incrementing where as the
post-increment returns it then increments the value. In your version you
begin the to write after the NIL, in mine I overwrite it.

#include <stdio.h>

char* strcpy(char* s, char* t) {
while(*++s);

while((*s++=*t++) != '\0');

return s;
}

int main(void) {
char message[100]="string1";
char* message2="string2";

strcpy(message, message2);
printf("%s\n", message);

return 0;
}

BartC
Guest
Posts: n/a

 10-30-2012
"Adrian Sch" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello! I am doing some exercises from K&R 2nd edition and I seem to be
> stuck: Here's a working copy of a custom strcpy:
>
> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;
>
> while((*s++=*t++))
> ;
>
> return ;
> }

Do you mean strcat rather than strcpy?

--
Bartc

Ben Bacarisse
Guest
Posts: n/a

 10-30-2012

> Hello! I am doing some exercises from K&R 2nd edition and I seem to be
> stuck: Here's a working copy of a custom strcpy:

No, it's a not-quite working version on strcat.

> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;

What is x for? You never use it.

> while((*s++=*t++))
> ;
>
> return ;

warning level to the highest you can. There's no reason not to get the

> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }

Also, get into the habit of layingout your code using some standard or
other. I know that the above layout could have been due to Google's
awful Usenet interface, but some of it is yours. Pick a style and stick
to it.

> And here's a version that doesn't work:
> char *strcpy(char * s, char * t)
> {
>
> while(*s++)
> ;
>
> while((*s++=*t++))
> ;
>
> return ;
> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
> It seems that for some reason the while(*s++) is 0

That makes not sense. A while loop always ends when it's condition is
zero. That's as true of the working as of the the non-working version.

> so it doesn't increment. Why? What am I missing here?

Play computer: draw a string and a pointer to it, then step through what
this loop does until you see what's wrong. I'll gladly tell you, but

+------------+
s: | o |
+-----+------+
|
V
+-----+-----+-----+-----+-----+-----+-----+-----+
| s | t | r | i | n | g | 1 | \0 |
+-----+-----+-----+-----+-----+-----+-----+-----+

(you'll need a fixed-width font to see this.)

--
Ben.

James Kuyper
Guest
Posts: n/a

 10-30-2012
On 10/30/2012 01:33 PM, Adrian Sch wrote:
> Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:
>
> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;
>
> while((*s++=*t++))
> ;
>
> return ;
> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
>
> And here's a version that doesn't work:
> char *strcpy(char * s, char * t)
> {
>
> while(*s++)
> ;
>
> while((*s++=*t++))
> ;
>
> return ;
> }
> int main(void)
> {
> char message[100]="string1";
> char * message2="string2";
> strcpy(message, message2);
> printf("%s", message);
> return 0;
>
> }
> It seems that for some reason the while(*s++) is 0 so it doesn't increment. Why? What am I missing here?

The 'x' is irrelevant. You may find it easier to understand what's going
on if you remove it. Your working version had the equivalent of:

while(*s) s++;

The version that didn't work had the equivalent of:

while(*s++);

When s points at "string1", how many times does s++ get executed with
the working version of the code? How many times with the version that
failed? In each case, where does s point after the loop is finished
executing?
--
James Kuyper

Eric Sosman
Guest
Posts: n/a

 10-30-2012
On 10/30/2012 1:33 PM, Adrian Sch wrote:
> Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:
>
> char *strcpy(char * s, char * t)
> {
>
> char x;
> while(x=*s)
> s++;
>
> while((*s++=*t++))
> ;
>
> return ;
> }

That's not a strcpy() work-alike. Looks more like strcat(),
which is a different breed of, well, cat.

> And here's a version that doesn't work:
> char *strcpy(char * s, char * t)
> {
>
> while(*s++)
> ;
>
> while((*s++=*t++))
> ;
>
> return ;
> }

This isn't a work-alike for any of the standard string
functions, and certainly not for strcpy() or strcat(). A name
like strabut() might describe what it does, which is: "Copy the
`t' string to the memory area just after the `s' string, leaving
the '\0' at the end of `s' undisturbed."

I think what you've overlooked is that the test in the first
`while' loop will detect the '\0' character *and* will advance
`s' past that character. If you want to append the `t' characters
to `s', you should deposit the first of them right where the '\0'
was originally; as things stand, you're depositing that first
character just after the '\0'.

--
Eric Sosman
http://www.velocityreviews.com/forums/(E-Mail Removed)d

Eric Sosman
Guest
Posts: n/a

 10-30-2012
On 10/30/2012 2:00 PM, Greg Martin wrote:
> [...]
> I made a couple of changes to your program. Some to make my compiler
> happy, some for readability and one to make the program work. The
> pre-increment will return the value after incrementing where as the
> post-increment returns it then increments the value. In your version you
> begin the to write after the NIL, in mine I overwrite it.
>
> #include <stdio.h>
>
> char* strcpy(char* s, char* t) {
> while(*++s);

This fails if `s' points to an empty string: It skips right
over the '\0' at the beginning and starts exploring the trackless
wilderness after the terminator. (It's very bad to find yourself
on the wrong side of The Terminator -- just ask Ahhnold.)

--
Eric Sosman
(E-Mail Removed)d

Greg Martin
Guest
Posts: n/a

 10-30-2012
On 12-10-30 12:17 PM, Eric Sosman wrote:
> On 10/30/2012 2:00 PM, Greg Martin wrote:
>> [...]
>> I made a couple of changes to your program. Some to make my compiler
>> happy, some for readability and one to make the program work. The
>> pre-increment will return the value after incrementing where as the
>> post-increment returns it then increments the value. In your version you
>> begin the to write after the NIL, in mine I overwrite it.
>>
>> #include <stdio.h>
>>
>> char* strcpy(char* s, char* t) {
>> while(*++s);

>
> This fails if `s' points to an empty string: It skips right
> over the '\0' at the beginning and starts exploring the trackless
> wilderness after the terminator. (It's very bad to find yourself
> on the wrong side of The Terminator -- just ask Ahhnold.)
>

Very true. Thanks Eric. There's a reason I hate those little shortcuts!

Guest
Posts: n/a

 10-30-2012
marČ›i, 30 octombrie 2012, 20:00:49 UTC+2, Greg Martin a scris:
> On 12-10-30 10:33 AM, Adrian Sch wrote:
>
> > Hello! I am doing some exercises from K&R 2nd edition and I seem to be stuck: Here's a working copy of a custom strcpy:

>
> >

>
> > char *strcpy(char * s, char * t)

>
> > {

>
> >

>
> > char x;

>
> > while(x=*s)

>
> > s++;

>
> >

>
> > while((*s++=*t++))

>
> > ;

>
> >

>
> > return ;

>
> > }

>
> > int main(void)

>
> > {

>
> > char message[100]="string1";

>
> > char * message2="string2";

>
> > strcpy(message, message2);

>
> > printf("%s", message);

>
> > return 0;

>
> >

>
> > }

>
> >

>
> > And here's a version that doesn't work:

>
> > char *strcpy(char * s, char * t)

>
> > {

>
> >

>
> > while(*s++)

>
> > ;

>
> >

>
> > while((*s++=*t++))

>
> > ;

>
> >

>
> > return ;

>
> > }

>
> > int main(void)

>
> > {

>
> > char message[100]="string1";

>
> > char * message2="string2";

>
> > strcpy(message, message2);

>
> > printf("%s", message);

>
> > return 0;

>
> >

>
> > }

>
> > It seems that for some reason the while(*s++) is 0 so it doesn't increment. Why? What am I missing here?

>
> >

>
>
>
> I made a couple of changes to your program. Some to make my compiler
>
> happy, some for readability and one to make the program work. The
>
> pre-increment will return the value after incrementing where as the
>
> post-increment returns it then increments the value. In your version you
>
> begin the to write after the NIL, in mine I overwrite it.
>
>
>
> #include <stdio.h>
>
>
>
> char* strcpy(char* s, char* t) {
>
> while(*++s);
>
>
>
> while((*s++=*t++) != '\0');
>
>
>
> return s;
>
> }
>
>
>
> int main(void) {
>
> char message[100]="string1";
>
> char* message2="string2";
>
>
>
> strcpy(message, message2);
>
> printf("%s\n", message);
>
>
>
> return 0;
>
> }

First, thanks to all of you for the replies.

Second, you are right, this a not-working strcat version.

Third, this is a very subtle problem and quite hard to identify consideringmy limited knowledge. Because my real question was why the "while(*s++);" gets skiped in the code. Because I was using a debuger and I was expecting some additional action. But because there was no block of code to execute and go back again to the while test, the while test was executed at once (very fast). Am I right or wrong? Because that seemed stupid to me, how the while get skipped while *s was pointing to s.
Now for the real question, that I didn't ask. I figured that the subtlety of the postfix increment is causing my trouble. Because once the *s is pointing at null, it is incremented one more time and the future copies of *t value go after the null. So when I am printing message, I have concatenated the string, but unfortunately after the null, and that makes it just (not random) garbage as far as printf is concerned.
I used a quick hack to fix it: using the prefix operator. That worked! But I think that this is wrong because if the first string's first character was null,then I'd repeat the whole affair from before and have concatenated the string after the null.

Forth, here's the fix(as sugested by some of you):
char *strcpy(char * s, char * t)
{

while(*s)
s++;

while((*s++=*t++))
;

return ;
}

Fifth, Is there any other way to keep simple and elegant, but on just one line of code? Or maybe a messier way, but also to fit in the while testing block? I am thinking and if else shortcut notation, but I don't master the idiom that well to do this apparently.