473,748 Members | 2,615 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

strcpy - my implementation

I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
/* My version of "strcpy - a C Library Function */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

enum { ARRSIZE = 101 };

char* my_strcpy( char*, char* );

int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
if( 2 != argc )
{
perror("USAGE: ./exec \" your input \"\n");
exit( EXIT_FAILURE );
}
else
{
strcpy( arr_in , argv[1] );
}

pc = my_strcpy( arr_out, arr_in );

while( *pc )
{
printf("*pc = %c\n", *pc++);
}

return EXIT_SUCCESS;
}

char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
=============== OUTPUT =============== =======

[arnuld@dune ztest]$ gcc -ansi -pedantic -Wall -Wextra check_STRCPY.c
[arnuld@dune ztest]$ ./a.out like
*pc = l
*pc = i
*pc = k
*pc = e
[arnuld@dune ztest]$

It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all. I really did not understand it.
Using thr array name will give a pointer to its 1st element but int htis
case it is giving a pointer to its last element. Why ? Thats why I
introduced the extra "char* pc" in first place.


--
www.lispmachine.wordpress.com
my email is @ the above blog.
Google Groups is Blocked. Reason: Excessive Spamming

Sep 8 '08 #1
77 8355
Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
That should be: char *strcpy(char *dest, const char *src);
char* pc;
pc = arr_out;
while( (*arr_out++ = *arr_in++) ) ;
return pc;
}
It works fine without troubles. Now if you change the last return call
in my_strcpy from "return pc" to return "return arr_out", then while
loop in main() will not print anything at all. I really did not
understand it. Using thr array name will give a pointer to its 1st
element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the string.

Your implementation is much slower than what that would be used in almost
any real c library, because it copies one byte at a time. If you know
something more about the way the target processor works than the C
standard tells you, then you can copy several bytes at a time using (for
example) int.

HTH
viza
Sep 8 '08 #2
arnuld said:
I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
/* My version of "strcpy - a C Library Function */

#include <stdio.h>
#include <stdlib.h>
I understand that you might need these for testing purposes...
#include <unistd.h>
....but why on earth do you need this non-standard header for testing an
implementation of a standard and rather simple C function?
#include <string.h>
Strange that you should need this, but okay.
enum { ARRSIZE = 101 };

char* my_strcpy( char*, char* );
Better: char *my_strcpy(char *, const char *);
>
int main( int argc, char** argv )
{
char* pc;

char arr_in[ARRSIZE];
char arr_out[ARRSIZE];

memset( arr_in, '\0', ARRSIZE );
memset( arr_out, '\0', ARRSIZE );
Or just:

char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

which saves you two memset calls.
if( 2 != argc )
{
perror("USAGE: ./exec \" your input \"\n");
exit( EXIT_FAILURE );
}
else
{
strcpy( arr_in , argv[1] );
What if argv[1] is longer than 100 bytes? You should test for this.

<snip>
char* my_strcpy( char* arr_out, char* arr_in )
Better: char *my_strcpy(char * arr_out, const char *arr_in)
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
How is this *your* implementation? It isn't significantly different from
the implementation on p105 of K&R2, with names changed to protect the
innocent and a return value added to get a closer match to ISO strcpy.

<snip>
It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all.
arr_out is badly named. In my_strcpy, it's not an array, but a pointer.

Consider what value that pointer has at the time you've completed the loop.
To which byte is it pointing? What value does that byte have? And
consequently, if you return it to main and capture that pointer value in
pc = my_strcpy(arr_o ut, arr_in), to what byte is pc pointing?

You would find it easier to learn and we would find it easier to explain if
you chose different names in called functions from those in calling
functions. When discussing your program, I can't refer to 'pc' without
saying which pc I mean. Nor can I refer to arr_in or arr_out without
saying which I mean. Had you used different names in my_strcpy, it would
have made discussion easier.
I really did not understand it.
Using thr array name will give a pointer to its 1st element
Yes. And that's what my_strcpy's arr_in is - a copy of a pointer to the
first element of an array. But then *you* change the value of that
pointer.
but int htis
case it is giving a pointer to its last element. Why ?
If you change an object's value, you should not be surprised if that
object's value changes.

Thats why I introduced the extra "char* pc" in first place.
Yes. It's necessary in this case. Well, there is another way round,
actually:

char *my_strcpy(char *target, const char *source)
{
size_t i = 0;
while(target[i] = source[i])
{
++i;
}

return target;
}

which avoids the extra pointer, but only at the expense of an extra size_t.

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 8 '08 #3
arnuld wrote:
>
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
As has been pointed out elsewhere, the source pointer should be const
and the names don't make sense. The inner parentheses in the while loop
are superfluous.
>
It works fine without troubles. Now if you change the last return call in
my_strcpy from "return pc" to return "return arr_out", then while loop in
main() will not print anything at all. I really did not understand it.
Using thr array name will give a pointer to its 1st element but int htis
case it is giving a pointer to its last element. Why ? Thats why I
introduced the extra "char* pc" in first place.
Because you have incremented it to point the the '\0' at the end of the
string.

--
Ian Collins.
Sep 8 '08 #4
viza <to******@gm-il.com.obviousc hange.invalidwr ites:
Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
>/* My version of "strcpy - a C Library Function */
>char* my_strcpy( char* arr_out, char* arr_in ) {

That should be: char *strcpy(char *dest, const char *src);
Oh for goodness sake.
>
> char* pc;
pc = arr_out;
while( (*arr_out++ = *arr_in++) ) ;
return pc;
}
>It works fine without troubles. Now if you change the last return call
in my_strcpy from "return pc" to return "return arr_out", then while
loop in main() will not print anything at all. I really did not
understand it. Using thr array name will give a pointer to its 1st
element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.

arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
If you increment it once it will be a pointer to a later address in
memory...
case, at the end of the function it will point past the end of the
string.
So what?
>
Your implementation is much slower than what that would be used in
almost
Much slower?
any real c library, because it copies one byte at a time. If you know
something more about the way the target processor works than the C
standard tells you, then you can copy several bytes at a time using (for
example) int.

HTH
viza
I would be interested to hear how you would do this in standard C.
Sep 8 '08 #5
Richard wrote:
viza <to******@gm-il.com.obviousc hange.invalidwr ites:
>Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
>>/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
>That should be: char *strcpy(char *dest, const char *src);

Oh for goodness sake.
Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
>>element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
>arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the
string.

So what?
He's answering the question, boy you are dense tonight..

--
Ian Collins.
Sep 8 '08 #6
Ian Collins <ia******@hotma il.comwrites:
Richard wrote:
>viza <to******@gm-il.com.obviousc hange.invalidwr ites:
>>Hi

On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
>>That should be: char *strcpy(char *dest, const char *src);

Oh for goodness sake.
Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
I was referring to the name change.
>
>>>element but int htis case it is giving a pointer to its last element.
Why ? Thats why I introduced the extra "char* pc" in first place.
>>arr_in is not an array, it is a pointer. If you increment the pointer
repeatedly it will be a pointer to a later address in memory. In this
case, at the end of the function it will point past the end of the
string.

So what?
He's answering the question, boy you are dense tonight..
I am pointing out that it has zero impact. So nothing to worry
about. But I could have, and should have, been more explicit.
Sep 8 '08 #7
On Sep 8, 11:21 am, Ian Collins <ian-n...@hotmail.co mwrote:
Richard wrote:
viza <tom.v...@gm-il.com.obviousc hange.invalidwr ites:
Hi
On Mon, 08 Sep 2008 11:51:45 +0500, arnuld wrote:
/* My version of "strcpy - a C Library Function */
char* my_strcpy( char* arr_out, char* arr_in ) {
That should be: char *strcpy(char *dest, const char *src);
Oh for goodness sake.

Now you are being an arse, the correction is correct. The second
pointer points to an invariant.
No, it's wrong.
It's C code, not a C implementation, therefore it shouldn't have the
name strcpy. (a hint that it's C code is that he includes several
standard header files, ignoring <unistd.hand that he has main there)
Sep 8 '08 #8

"Ian Collins" <ia******@hotma il.comwrote in message
news:6i******** ****@mid.indivi dual.net...
arnuld wrote:
>>
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;

pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;

return pc;
}
The inner parentheses in the while loop
are superfluous.
I thought this was sometimes used to stop the compiler warning about using
"=" instead of "==".

--
Bartc

Sep 8 '08 #9
"arnuld" <su*****@invali d.addresswrote in message
news:pa******** *************** *****@invalid.a ddress...
>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
char* my_strcpy( char* arr_out, char* arr_in )
{
char* pc;
if (arr_out==NULL| |arr_in==NULL)r eturn "";

Testing for null strings might be useful; either return empty string or
abort. But not everyone agrees.
pc = arr_out;

while( (*arr_out++ = *arr_in++) ) ;
If you're interested in speed you might like to test your version against
the standard strcpy, for various lengths of strings and copying a few
million times.

You might then also like to test a version using strlen() and memcpy().

--
Bartc

Sep 8 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
3347
by: Paul Sheer | last post by:
I need to automatically search and replace all fixed size buffer strcpy's with strncpy's (or better yet, strlcpy's) as a security and stability audit. The code base is large and it is not feasable to manually perform these changes. I would like perhaps a C++ parser that can automatically detect use of a strcpy to a buffer of fixed size. For instance, struct x { char member;
4
4363
by: A_StClaire_ | last post by:
guys, this is the code for strcpy, as most of you probably know and I found out recently: void str_copy(char* ptr1, char* ptr2) { for( ; *ptr1 = *ptr2; ++ptr1, ++ptr2); }
44
5807
by: Nicolas | last post by:
On most implementations of the standard C library, the functions that copy characters in a previously allocated buffer, like strcpy or strcat, are returning the pointer to that buffer. On my NetBSD system, man strcpy gives the following prototype : char *strcpy(char * restrict dst, const char * restrict src); What's the point in returning a pointer we already know before the call? Thank you in advance for an explanation.
1
2869
by: Josh Wilson | last post by:
Hey gang, So I have my stdin which is user defined file, and am wanting to write it to a temporary file (seems odd I know, but there is a sincere reason), and then use that file as the stdin for the remaining part of the program. I have combed the FAQ and got some preliminary questions answered, and tried to model this after what I have seen suggested to people previously, but for my strcpy and freopen I get, "warning: passing arg 1 of...
81
7329
by: Matt | last post by:
I have 2 questions: 1. strlen returns an unsigned (size_t) quantity. Why is an unsigned value more approprate than a signed value? Why is unsighned value less appropriate? 2. Would there be any advantage in having strcat and strcpy return a pointer to the "end" of the destination string rather than returning a
302
18557
by: Lee | last post by:
Hi Whenever I use the gets() function, the gnu c compiler gives a warning that it is dangerous to use gets(). Is this due to the possibility of array overflow? Is it correct that the program flow can be altered by giving some specific calculated inputs to gets()? How could anyone do so once the executable binary have been generated? I have heard many of the security problems and other bugs are due to array overflows.
38
2725
by: edu.mvk | last post by:
Hi I am using strcpy() in my code for copying a string to another string. i am using static char arrays. for the first time it is exected correctly but the second time the control reaches then the SEGMENTATION FAULT is occuring. Please tell me what are all the cases this problem may occur if we use strcpy().
16
309
by: mdh | last post by:
I have a question about the library function strcpy. In K&R on page 109, strcpy is used to copy a line ( line ) to a pointer (char *), which is first allocated space by K&Rs "alloc" function. In a few pages prior to this, the example that K&R showed used this definition for it's version of strcpy void strcpy( char *s, char *t){ while ( *s++ = *t++);
0
8996
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9562
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9386
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
6799
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6078
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4879
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3319
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
2791
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2217
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.