473,698 Members | 2,445 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
77 8330
Bartc said:
>
"Ian Collins" <ia******@hotma il.comwrote in message
news:6i******** ****@mid.indivi dual.net...
>arnuld wrote:
>>>
<snip>
>> 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 "==".
Right, and in that respect the parentheses are not superfluous in code
intended to be compiled by implementations that recognise that construct
as having that meaning. They /are/ superfluous from a C perspective,
because they can be removed without affecting the semantics of the code.
So whether or not they are truly superfluous really depends on what you
mean by "superfluou s".

--
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 #11
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};
What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
Sep 8 '08 #12
Richard Heathfield wrote:
arnuld said:
>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;
You could change that to

char *const pc = arr_out;
> while( (*arr_out++ = *arr_in++) ) ;
/* I would go even further than just extra parentheses: */

while ((*arr_out++ = *arr_in++) != '\0') {

/*
** There are some coding guidelines against writing
** an entire loop with only an empty statement on one line.
** Some programmers, including myself,
** always use a compound statement
** with an if statement or a loop statement.
*/
;
}
>>
return pc;
}
http://www.psgd.org/paul/docs/cstyle/cstyle.htm
http://www.psgd.org/paul/docs/cstyle/cstyle08.htm

--
pete
Sep 8 '08 #13
Sjoerd wrote:
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
> char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
Your expectation is incorrect. If you explicitly initialize any elements
of an array or any members of a structure, all of the remaining array
elements or structure members are implicitly zero-initialized.
Sep 8 '08 #14
Sjoerd wrote:
On Mon, 08 Sep 2008 07:55:15 +0000, Richard Heathfield wrote:
> char arr_in[ARRSIZE] = {0};
char arr_out[ARRSIZE] = {0};

What does this do? How does it work? You seem to initialize only one
element of the array, so I expect that it does not set the whole content
of the array to 0.
That the way it seems
if you don't know the relevant parts of the C language.

char arr_in[ARRSIZE] = "";

is yet another way to initialize the entire array to null characters.

A short initializer, sets the remaining elements
as though they were each initilzed with {0}.

char array[10] = {'A'};
or
char array[10] = "A";

gives you an array with one element equal to ('A'),
followed by nine array elements, each equal to ('\0').

--
pete
Sep 8 '08 #15
Richard Heathfield <rj*@see.sig.in validwrites:
arnuld said:
>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
[...]
>>
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.
Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.

[snip]
>{
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.
It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code. I suspect if you put 100 C programmers
in clean rooms and asked them to write an implementation of strcpy,
you'd only get about three essentially different versions, and this is
one of them. K&R is probably the most memorable appearance of the
`*p++ = *q++' idiom, but just because one saw it there and continues
to use it doesn't make one a plagiarist. It's a textbook, after all.
Sep 8 '08 #16
Nate Eldredge <na**@vulcan.la nwrites:
Richard Heathfield <rj*@see.sig.in validwrites:
>arnuld said:
>>I have created my own implementation of strcpy library function. I would
like to have comments for improvements:
[...]
>>>
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.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
You think
> char arr_in[ARRSIZE] = {0};
camouflages it? To be honest after spending time in c.l.c I get the
heebygeebies whenever I see memset with arrays - I'm not really sure
whats a character anymore, whats an array etc. I wonder if that memory
has "alignment issues" with "special pointers" etc etc. I used to think
of them as blocks of memory and all my programs just worked. c.l.c put
paid to that... :-;
>
[snip]
>>{
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.

It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code. I suspect if you put 100 C programmers
in clean rooms and asked them to write an implementation of strcpy,
you'd only get about three essentially different versions, and this is
one of them. K&R is probably the most memorable appearance of the
`*p++ = *q++' idiom, but just because one saw it there and continues
to use it doesn't make one a plagiarist. It's a textbook, after all.
You would be amazed at how few would actually do it this way. There are
many people out there who discourage such stuff. I even read here once
that it "misuses C" ... the mind boggles. I have seen many code bases
where you hardly ever see a pointer used in its natural habitat. A
crying shame IMO.

Sep 8 '08 #17
Nate Eldredge <na**@vulcan.la nwrites:
[...]
Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
[...]

Why do auto arrays have to be zeroed? There's certainly no C
requirement for this; any such requirement would have to be
system-specific.

Of course an implementation is certainly allowed to zero auto objects.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '08 #18
On Sep 8, 7:47 pm, Nate Eldredge <n...@vulcan.la nwrote:
Richard Heathfield <r...@see.sig.i nvalidwrites:
arnuld said:
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.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway. My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
Nonsense. memset sets the bit pattern to 0. {0} Sets pointers to NULL,
floating point objects to 0.0, integers to 0, etc.
They are not equivalent.
Sep 8 '08 #19
Nate Eldredge said:
Richard Heathfield <rj*@see.sig.in validwrites:
>arnuld said:
<snip>
>>>
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.

Well, it appears to. But in a typical implementation, when auto
objects are on the stack, the arrays would have to be zeroed out at
runtime anyway.
Fine, but that's the implementation' s problem. The saving is in the source
code: economy of expression.
My own implementation actually generates a call to
memset to accomplish this. So the effect is probably the same, both
in behavior and performance. And one could argue that it is
stylistically preferable to make the memset call explicit, since it
avoids camouflaging a potentially expensive operation.
It isn't very good camouflage, though, since any experienced C programmer
will recognise it for what it is. It's just a more elegant way to write
the code. We don't write char foo[8] = { 'H', 'e', 'l', 'l', 'o', '\0',
'\0', '\0' } just because it makes explicit the fact that eight characters
are being copied into the array. We write char foo[8] = "Hello", and trust
that competent programmers will understand.
>
[snip]
>>{
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.

It's hardly necessary to make veiled accusations of plagiarism for
such a trivial piece of code.
I don't think it would be reasonable to call it plagiarism, since it's
blindingly obvious to all concerned that it's basically the K&R2 code. I
was just pointing out that "my own implementation" wasn't really the right
way to describe it.

--
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 #20

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

Similar topics

7
3342
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
4360
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
5802
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
2866
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
7305
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
18487
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
2714
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
8675
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
8604
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9029
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
8897
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8862
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5860
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
4619
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3050
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
3
2002
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.