Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1342
  • Last Modified:

strcpy() and arrays

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
krampovpi
Asked:
krampovpi
  • 11
  • 8
  • 5
  • +3
1 Solution
 
VoteyDiscipleCommented:
This sounds awfully homework-like.  Is it?
0
 
ozoCommented:
while( *s1++=*s2++ ){}

but what does strcpy(char[], const char ch) do?
0
 
SinclairCommented:
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
jhshuklaCommented:
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
 
yogesh28577Commented:
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
 
SinclairCommented:
That code doesn't work. It only copies the first character. Unless that was the goal...
0
 
jhshuklaCommented:
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
 
MathematixCommented:
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
 
jhshuklaCommented:
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
 
MathematixCommented:
In that case I go with ozo's answer. Other solutions that avoid iterating through the character array seem to produce undefined results. :)
0
 
jhshuklaCommented:
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
 
MathematixCommented:
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
 
SinclairCommented:
Ok, but what if their string is 30 characters long ?
0
 
MathematixCommented:
Just increase all the constants to 30. ;)

When I get bored I'll probably do it for variable length strings.
0
 
jhshuklaCommented:
>> variable length strings.
that's what we want.
0
 
MathematixCommented:
Feel free to have a go then.
0
 
MathematixCommented:
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
 
SinclairCommented:
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
 
MathematixCommented:
Twice as slow?! How did you come to that conclusion? I'm shifting memory where ozo's iterate's through the string.
0
 
SinclairCommented:
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
 
MathematixCommented:
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
 
SinclairCommented:
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
 
MathematixCommented:
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
 
SinclairCommented:
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
 
MathematixCommented:
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
 
MathematixCommented:
BTW, given that you are confident that you have a better solution, why not improve on my implementation to prove your points?
0
 
ozoCommented:
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
 
SinclairCommented:
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 11
  • 8
  • 5
  • +3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now