Solved

strcpy() and arrays

Posted on 2006-11-06
28
1,211 Views
Last Modified: 2008-01-09
I'm trying to write my own definition of strcpy() using array notation. I want to  know what is the code that implements the function.
using : these 2 prototype situations
#1
char strcpy(char[], const char ch)
      {

      }
and
#2
char strcpy(char *s1, const char *s2);
      {

      }
0
Comment
Question by:krampovpi
  • 11
  • 8
  • 5
  • +3
28 Comments
 
LVL 19

Expert Comment

by:VoteyDisciple
ID: 17885359
This sounds awfully homework-like.  Is it?
0
 
LVL 84

Expert Comment

by:ozo
ID: 17885363
while( *s1++=*s2++ ){}

but what does strcpy(char[], const char ch) do?
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17886017
What ozo said. Actually, re-implementing strcpy using array notation is a bad idea (ok, re-implementing strcpy at all is  a bad idea, but I digress), because it will be a lot less efficient than ozo's version.

Additionally, your teacher should've told you that using strcpy at all is a terrible idea; you should only use strcnpy.
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 17887180
i believe strcpy(char[], const char ch) fills the string with ch. anyways, i will abstain from posting code until it is clear that it is not homework or until the asker shows what s/he has accomplished so far.
so krampovpi, what do we have so far?
0
 
LVL 1

Expert Comment

by:yogesh28577
ID: 17888279
here i give full source code


#include <iostream.h>
 

char strcpy(char[], const char);
char strcpy(char *, const char *);
main()
{
const char b='A';
char a[10];
cout<<strcpy(a,b);
char *c;
const char *d="a";
cout<<strcpy(c,d);

}

char strcpy(char a[], const char ch)
     {
     a[0]=ch;
      return a[0];
     }

   char strcpy(char *s1, const char *s2)
     {
       *s1=*s2;
      return *s1;

     }

0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17891282
That code doesn't work. It only copies the first character. Unless that was the goal...
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 17891431
yogesh, that is totally wrong.

let krampovpi show us what he thinks needs to be done in copying a string. and i am not asking for syntactically correct code. pseudocode or algorithm will do. we can then help him translate it to C/C++
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17892831
strcpy() is a very simple function that can be implemented in five minutes. I have provided some actual code below that does not provide an 'array notation' but simply copies a string. I have also left out a lot of explanation as an excercise for you to work out exactly how it works.

#include <iostream>            // We include this header to print the string to console.
using std::cout;            // std::cout is the standard implementation for printing a string to console.
using std::cin;                  // std::cin is the standard implementation for reading strings and other types.
using std::endl;            // std::endl is the standard implementation to flush the input stream buffer and force a new line.

#include <string>            // Header to include the string object with operations defined.
using std::string;            // Inclusion of the string object defined in the C++ standard.

extern "C"
{
#include <memory.h>
}

void myStrCpy(string source, string *dest);

int main()
{
      string sourceString;
      string destString;

      cout << "Please enter a string: ";
      cin >> sourceString;

      myStrCpy(sourceString, &destString);

      cout << "And here is your copied string!: " << destString << endl;

      return 0;
}

void myStrCpy(string source, string *dest)
{
      memset((string*)dest, 0, sizeof(string));

      *dest = source;
}

Have fun! :)
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 17895555
Wow mathematix! Please read the question again. It is asking for how to implement strcpy; not how to copy a string using any means available.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17907910
In that case I go with ozo's answer. Other solutions that avoid iterating through the character array seem to produce undefined results. :)
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 17910554
I too will go with that answer.

krampovpi, are you still there? you do not seem to be interested in the discussions going on here.
0
 
LVL 1

Accepted Solution

by:
Mathematix earned 250 total points
ID: 17910564
Hold on! Here is the solution that I finally worked out. It's bad to have a tired jhead when doing this, but I couldn't let it go. My last post was gibberish after a whole day at the studio. :)

// This project has been compiled as pure C code (/TC).

#include <stdio.h>
#include <memory.h>

void strcpy(char *s1, const char *s2);

int main()
{
      char sourceString[25];
      char destString[25];

      printf("Please enter a string: ");
      scanf("%s", &sourceString);


      printf("Copying: %s\n", sourceString);
      strcpy(destString, sourceString);

      printf("And here is your copied string: %s\n", destString);

      return 0;
}

void strcpy(char *s1, const char *s2)
{
      memcpy(s1, s2, sizeof(char) * 25);      
}
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17910712
Ok, but what if their string is 30 characters long ?
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17913694
Just increase all the constants to 30. ;)

When I get bored I'll probably do it for variable length strings.
0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 9

Expert Comment

by:jhshukla
ID: 17913826
>> variable length strings.
that's what we want.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17913846
Feel free to have a go then.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17929367
Given the function parameters, this is the best that I can do for a variable length string program.

// This project has been compiled as pure C code (/TC).

#include <stdio.h>
#include <memory.h>

#define MAX_LENGTH 25

int stringLength;

void strcpy(char *s1, const char *s2);

int main()
{
     char sourceString[MAX_LENGTH];
     char destString[MAX_LENGTH];

     printf("Please enter a string: ");
     scanf("%s", &sourceString);

       stringLength = sizeof(char) * MAX_LENGTH;
       printf("String size to be copied over is: %i\n", stringLength);

     printf("Copying: %s\n", sourceString);
     strcpy(destString, sourceString);

     printf("And here is your copied string: %s\n", destString);

     return 0;
}

void strcpy(char *s1, const char *s2)
{
     memcpy(s1, s2, sizeof(char) * stringLength);    
}
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17933938
Mathematix:

Your code does what ozo's code does, only twice as slow (ok, maybe only 1.5 times or so) and with global variables. And it can still only copy strings up to MAX_LENGTH characters in size.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17934023
Twice as slow?! How did you come to that conclusion? I'm shifting memory where ozo's iterate's through the string.
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17934188
Sorry, my bad, for some reason I thought you were using strlen. Still, you are always copying MAX_LENGTH characters, whereas ozo copies only the characters he needs. I guess this all depends on which CPU you use. If you use a CPU that allows you to copy large chunks of memory quickly (maybe a GPU), then your solution is best; otherwise, ozo's is. For MAX_LENGTH = 25, your solution will most likely be faster, but I expect the speed advantage to drop off as you increase MAX_LENGTH.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17934418
What i have offered is not the perfect solution. Just something that contributes towards answering the original poster's question.

In the majority of cases it is very, very hard to argue against moving blocks of memory over iterating through an array, or any other approach for that matter, and this is the reason why I prefer taking advantage of C and C++'s lower level operations to achieve many such tasks.

Regarding the timings, I wouldn't speculate beyond the following:

1. If the string is very short, but the array is very large then the timings could be in ozo's favour purely because a contiguous block of memory (depending on the implementation) will need to be found, and the larger the block, the more likely the longer the search time will be.

2. Arrays are simply a high-level implementation of iterating through memory from a base address of the array (&a[0]) and iterating through the structure in blocks of sizeof(type). For the reasons specified above, copying a block of memory from &a[0] to &a[n-1] where 'n' is the total number of elements is most certainly faster.

I fail to see the relevance of the benefits of either technique that would differ between a CPU and a GPU. Ultimately all hardware, ignoring enhanced implementations, will yield the same results.
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17934525
Firstly, in your case, you are pre-allocating the destination array on startup, so allocation performance isn't an issue.

Secondly, copying memory can, and often is, very expensive. Most CPUs use the following algorithm for memcpy (only in Assembly, of course):

register byte *src = sourceBuffer, *dest = destBuffer;
register int count;
register byte tmp;

for(count = bufferSize; count > 0; src++, dest++, count--) {
  tmp = loadMemoryAt(src);
  storeMemoryAt(dest, tmp);
}

The problem is that the loadMemoryAt and storeMemoryAt instructions are slow, because RAM is slow compared to the CPU. Usually, they take several CPU cycles to execute, whereas normal ALU operations take one instruction each (or less, even). This means that avoiding extra memory copying is a worthy optimization goal. This is especially true on smaller, embedded processors, but it's still true of x86s, as well.

However, most modern CPUs come with special memcpy instructions that implement memory copying in hardware; however, the amount of memory you can copy, and the time it takes, is still limited by the CPU. GPUs, on the other hand, do nothing but push memory around most of the time, so their built-in memcpy is really, really fast; they have tons of hardware logic that does nothing but memcpy. Thus, for really large strings, you'd be better off using the GPU.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17934706
You're using a loop again. This is not my point. Feel free to present actual assembly code to back up your case and I'll take it apart. :)
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17934808
Well, here's what IBM has to say (courtesy of a random Google search):

http://www-128.ibm.com/developerworks/library/l-ia.html#h11

In theory, how would you copy a chunk of memory without using a loop, either explicitly C or implicitly in assembly ? My loop above was pseudocode for assembly, btw.

0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17934866
Dude, you are really beginning to lose me. This is a random article on the how-to in assembly language.

Of course when you are moving along memory you are "iterating through it", but where the difference is is how efficiently you iterate through it. I could use inline assembly, but that is not what the topic starter intended, i would imagine, and i'm not one for ego battles. I've made my point.

We have gone way off topic from that intended by the topic starter. I will now only answer questions directly relevant to the original topic.
0
 
LVL 1

Expert Comment

by:Mathematix
ID: 17934873
BTW, given that you are confident that you have a better solution, why not improve on my implementation to prove your points?
0
 
LVL 84

Expert Comment

by:ozo
ID: 17934900
Sometimes you can speed things up by unrrolling the loop.
Some machines have special instrictions for moving blocks of memory.
Sometimes this just does the same loop in microcode, sometimes they can make use a bus width larger than 8 bits, with various tricks to stop at the right place when the block is not aligned.
But a good compiler should optimize your loop into whatever works best on the target machine.
The built in strcpy function for your machine should have been written with those considerations in mind.
0
 
LVL 2

Expert Comment

by:Sinclair
ID: 17934921
Yeah, ozo is right, ultimately. My preferred implementation of strcpy is " while( *s1++=*s2++ ){} " (which is what ozo said), but I only re-implement it when I'm using PIC16 or something. Ozo is right in saying that, for optimal performance, you should use the built-in implementation for your machine.
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Purpose To explain how to place a textual stamp on a PDF document.  This is commonly referred to as an annotation, or possibly a watermark, but a watermark is generally different in that it is somewhat translucent.  Watermark’s may be text or graph…
Whether you’re a college noob or a soon-to-be pro, these tips are sure to help you in your journey to becoming a programming ninja and stand out from the crowd.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now