Implementing strcpy without <string.h>

In summary: Use ++s1 and ++s2 rather than s1++ and s2++. You should only use ++ as a postfix when it's embedded in a larger expression and you want to increment after evaluating the rest of the expression.
  • #1
galaxy_twirl
137
1
Moved here from non-homework forum, therefore template is missing
Hi everyone. I ran into a problem while trying to code the string function, strcpy, without the use of <string.h>. The function, strcpy, which I have to make myself is exactly the same as the strcpy in <string.h>.The question in my homework is:

Implement the my_strcpy(s1,s2) function that copies string s2 to s1, including the terminating null character, topping after the null character has been copied. String s1 is returned. Use char *my_strcpy(char* s1, const char* s2) as your function and write the main program to test the functionality of your function.

My codes are below:

Code:
 #include <stdio.h>

char *my_strcpy(char* s1, const char* s2);

int main(void)
{
     char str1[4]={"Cat"};
     char str2[4]={"Dog"};
    char* s1;
    char* s2;
    s1 = &str1[0];
    s2 = &str2[0];

   my_strcpy(s1, s2);

   printf("New string: %s\n", s1);

   return 0;
}

char *my_strcpy(char* s1, const char* s2)
{
     while(s1 <= s2)
     {
         *s1 = *s2;
          s1++;
          s2++;
     }
      return;
}

When I ran the above code, it gave me a segmentation fault. I have a feeling there is something wrong with my printf and my_strcpy function (in terms of how it is called in main) and most prolly, my loop construct, cos a seg. fault probably means my program accessed memory it was not allocated with.

Any help is greatly appreciated! :D

Warmest Regards,

galaxy_twirl
 
Last edited:
Physics news on Phys.org
  • #2
First of all, post your code inside [ code ] [ /code ] tags (without the spaces), so indentations aren't lost.

Now ask yourself, within my_strcpy(), when is s1 <= s2 true, and when is it false, and why do think that's relevant?

(As an aside, didn't your compiler complain that my_strcpy() didn't return anything?)
 
  • #3
DrGreg said:
First of all, post your code inside [ code ] [ /code ] tags (without the spaces), so indentations aren't lost.

Now ask yourself, within my_strcpy(), when is s1 <= s2 true, and when is it false, and why do think that's relevant?

(As an aside, didn't your compiler complain that my_strcpy() didn't return anything?)

Hi DrGreg. I have put my codes into the <code> blocks. Thank you.

My idea is that as long as string1 has a corresponding box with string2, I will copy the respective element in string2 box into string1 box. When s1<=s2 is false, the loop will stop and return the result from the my_strcpy function to the main function.

Oh wait. I forgot that I re-edited my code before I compiled with gcc in vim. Before I edited the code, vim returned a seg. fault, but now, everything compiles nicely, but I still got 'Cat' back.

However, when I put gcc -Wall, it gave:
tut9q1b.c: In function 'my_strcpy':
tut9q1b.c:30:2: warning: 'return' with no value, in function returning non-void

which I think is what you mentioned right?
 
Last edited:
  • #4
Ah! I think I know why... my_strcpy is not a void function, so I must return something at the end of it to the main function! Gosh. What am I doing?! >< I will try again. Thank you for pointing out my mistake. :)
 
  • #5
What if s1 and s2 are of different lengths? Then your function doesn't work.

Also, use ++s1 and ++s2 rather than s1++ and s2++. You should only use ++ as a postfix when it's embedded in a larger expression and you want to increment after evaluating the rest of the expression.

char * my_strcpy (char* s1, const char* s2)
{
char * temp = s1;
while (s1 && s2)
*s1++ = *s2++;
if (s1 != s2) throw ("Uh oh ...");
else return temp;
}
 
  • #6
Jamin2112 said:
What if s1 and s2 are of different lengths? Then your function doesn't work.

Also, use ++s1 and ++s2 rather than s1++ and s2++. You should only use ++ as a postfix when it's embedded in a larger expression and you want to increment after evaluating the rest of the expression.

char * my_strcpy (char* s1, const char* s2)
{
char * temp = s1;
while (s1 && s2)
*s1++ = *s2++;
if (s1 != s2) throw ("Uh oh ...");
else return temp;
}

Hi Jamin2112. Thank you for your reply. I am assuming that the user will put s1 and s2 of the same lengths. :) I did not learn pre-increment in my course, so I don't think I know how to use that properly, so I will stick to s1++ for the time being. Thank you.
 
  • #7
Jamin2112 said:
Also, use ++s1 and ++s2 rather than s1++ and s2++. You should only use ++ as a postfix when it's embedded in a larger expression and you want to increment after evaluating the rest of the expression.

First time I hear such a thing.

while (s1 && s2)

Segmentation fault waiting to happen.
 
  • #8
galaxy_twirl said:
When s1<=s2 is false

This is not the condition you are looking for. You need to check if the character copied (the one pointed to by s1) is not zero.
 
  • #9
Hi Borek. Thank you for your reply. I managed to solve the question after my teacher explained the answer to me. Thank you! :D And yupp, the first thing in the while loop is, "while(s2 != '\0')" to make sure the first element is not null, if it is null, nothing will be copied.
 
  • #10
galaxy_twirl said:
while(s2 != '\0')

Better, but still wrong. You are comparing a pointer to '\0', that's not what you should do.

Do you understand the difference between pointer and the object it points to?

IOW: what is the difference between s1 and *s1?
 
  • #11
Borek said:
Better, but still wrong. You are comparing a pointer to '\0', that's not what you should do.

Do you understand the difference between pointer and the object it points to?

IOW: what is the difference between s1 and *s1?

Oh my gosh! Sorry. I think I left out a star in front of s2. It should be "while(*s2 != '\0')".

Yes, I understand the difference between a pointer and the object it points to. A pointer is something that points to the address of something, like int* ptr, is a pointer bearing the name, "ptr", pointing to the address of an integer value. Am I right?

s1 is a pointer pointing to the first box of str1, as I defined
Code:
char* s1;
then, I wrote
Code:
s1 = &str1[0];
in main program.

Sorry. ><

Thank you for pointing out my mistake. I am struggling to learn C as the teacher goes very fast so I am pretty much lagging behind. Do you have any advice for me? I know that practice is of paramount importance when it comes to programming, especially for an absolute new beginner. However, I keep finding that I get stuck whenever I try to solve the questions given to me by my teacher, thus I find it very hard to proceed on. :( Hence, may I know if you have any advice for me? Thank you once again. :)[/code]
 
  • #12
I'd say you are on the right track. Pointer arithmetic was the hardest part for me.

How can you debug errors? Use simple examples where you can track every step. Also when something works as expected.
Finally I'd advise to try and understand the task at hand as good as possible. For functions like these that's a small task.
When you implement a simulation, for example you need to understand the algorithms and the problem you are going to solve very well.

For now, keep going at it. It seems that you understand the issues with your code whenever they are brought up. Which means to me that you are capable already, just a bit chaotic/over enthusiastic in your coding endeavours :-)
 
  • #13
Hi JorisL. Thank you. :) Oh yes, pointers are very confusing. They are still confusing to me, especially when my teachers passes pointers from functions to functions, etc.

I see. I am currently in a University now, so most of the tasks now required quite complex codes as we are gearing up for the final exams. For now, I try to write the pseudocodes first before proceeding, which I think helps a little, rather than having to digest a large chunk of information all at once. :) Algorithms are the most irritating thing I think. If one is unable to get the algorithm, the question is as good as gone.

Yupp I will. Actually, I am not very clear, but I think I can get a gut feeling of where I am wrong. :X Thanks again for your encouragement! :D:D I really appreciate it. :)
 
  • #14
galaxy_twirl said:
Oh my gosh! Sorry. I think I left out a star in front of s2. It should be "while(*s2 != '\0')".

That's OK, although it can be still simplified - just

Code:
while (*s2)

will do. Whether it is a better coding or not - some will say it is, some will say it is not. You don't have to write it this way, but understanding why it can be written this way is important.

Yes, I understand the difference between a pointer and the object it points to. A pointer is something that points to the address of something, like int* ptr, is a pointer bearing the name, "ptr", pointing to the address of an integer value. Am I right?

Point to something, not to address of something.

s1 is a pointer pointing to the first box of str1, as I defined
Code:
char* s1;
then, I wrote
Code:
s1 = &str1[0];
in main program.

Code:
s1 = str1

will do - an array is a pointer. From what I know what you wrote sometimes is equivalent, but sometimes is not; I believe someone posted recently piece of code that generated runtime errors in a very similar situation.

Thank you for pointing out my mistake. I am struggling to learn C as the teacher goes very fast so I am pretty much lagging behind. Do you have any advice for me? I know that practice is of paramount importance when it comes to programming, especially for an absolute new beginner. However, I keep finding that I get stuck whenever I try to solve the questions given to me by my teacher, thus I find it very hard to proceed on. :( Hence, may I know if you have any advice for me? Thank you once again.

I am afraid I don't have any simple advice, other than what you already know. Feel free to ask your questions here.
 
Last edited by a moderator:
  • #15
Thank, you, Borek. :)

I don't understand why "while(*s2)" is equivalent to "while(*s2 != '\0')". I thought I must specifically tell the program to stop when it hits a null character? I am not sure if I am correct, but if I link it to the idea of str in C, it automatically terminates on a null char. Is this why you can write "while(*s2)"?

Oh. A pointer points to something, and it holds the address of that thing it points to.

I see. My teacher told me that too:
Borek said:
an array is a pointer
. I guess this is the confusing part on pointers.

It's alright. I will continue practising. Thanks for your help! :) Okay. I think I ran into a problem again for a new problem. Let me post a new thread. ><
 
  • #16
galaxy_twirl said:
I guess this is the confusing part on pointers.

That's why I usually access arrays, even those passed as pointers, using the square bracket-indices.

Code:
while( *s2 ){
   s2++;
   //do stuff
}
will terminate at the last character of a string, the string null terminator has various representations (might be somewhat bad terminology).
One of them is '\0', the other one of interest is NULL.
See for example http://en.wikipedia.org/wiki/ASCII#ASCII_control_code_chart
Now if you use
Code:
while(*s2 != '\0')
The while-loop continues until you hit '\0', the expression *s2 != '\0' will evaluate as false and terminate the loop.
We have that NULL is the same as FALSE in C, that is why both codes are equivalent Another code that will move through the string and end up pointing to the first location after the string is
Code:
while(s2){
   s2++;
   //do stuff
}

You can check this behaviour to get acquainted with some different approaches handling strings.
One last point, only strings should be null terminated. An array of integers manipulated using pointer arithmetic will require you to think a little different
 
  • #17
JorisL said:
Another code that will move through the string and end up pointing to the first location after the string is
Code:
while(s2){
   s2++;
   //do stuff
}

If s2 is a pointer, this is plain wrong. Loop will end once s2 point to memory address 0x0, not when the content of what it points to is zero.

So far your posts have been 50/50 right and wrong, please don't confuse OP.
 
  • #18
To JorisL: I think I am much clearer now after your explanation. :D Thank you so much! :D

To Borek: I see. Just wondering, is pointing to 0x0 the same as pointing to NULL? (I have a feeling it is not.) Haha. Dont' worry, I think it is okay if JorisL posts something wrong, because the other programmings pros can point the mistake out and we can learn in the process. Thanks a lot for your help! I shall go and look at my strcat.. I seemed to have made a lot of mistakes. Sigh.
 
  • #19
galaxy_twirl said:
Just wondering, is pointing to 0x0 the same as pointing to NULL?

Depends on what you mean by "pointing to".

Technically pointer is just an address of the memory position (which means it is just an integer number). So "pointing to 0x0" can mean either "pointing to memory position which holds number 0" or "pointing to memory position located at memory address 0 and containing something".
 
  • #20
I see. Oh oops. :X Sorry. I keep linking the word pointer to pointing. :X Thanks for the clarification! :D
 
  • #21
One of the toughest roadblocks for beginning programming students to comprehend is the concept of pointers. Over the course of many years of teaching C and other programming languages in colleges and industry, I came up with a visual aid to help get the ideas across.

The illustration below is intended to be a visual representation of this code:
C:
int num = 17;
int * ptr = &num;

In the upper left corner of each box in the drawing is the name of the variable, with ptr being the name of the pointer variable, and num being the name of the other variable. The upper right corner of each box holds the location in memory of the variable. I'm assuming that num is stored at memory location 100. In a real program, the address of the variable won't be 100, but I'm using 100 for simplicity. The ptr variable is also stored somewhere in memory, but I don't care where it is, so I didn't include its address in my drawing.

The value that is stored in a pointer variable is an address. In the illustration, ptr's value is 100, the assumed location in memory of num. When a pointer variable is initialized with a valid memory location in memory, we say that the pointer variable "points to" or is a "pointer to" that location. The arrow in the illustration means that ptr points to num's memory location.

Pointers.jpg


One thing we can do with a pointer is dereference it (using the * operator) to read from or write to the memory location it points to. If I add a line to the code above l add a line to the code above, let's see what happens.
C:
int num = 17;
int * ptr = &num;
*ptr = 25;

By dereferencing ptr, I don't change the value of ptr -- I change the value of what ptr points to. The effect of the last line of code is to change the value of num to 25.
 
Last edited:
  • #22
Thank you, Mark44. I think I am much clearer after your explanation and diagram. :D Thank you for taking time off to do such a detailed explanation. :)
 

1. How does the strcpy function work?

The strcpy function works by copying a string from one location to another. It takes two arguments - the destination string and the source string. It then iterates through the source string and copies each character to the destination string until it reaches the null character at the end of the source string.

2. Why would someone want to implement strcpy without ?

There are a few reasons why someone might want to implement strcpy without :

  • Some embedded systems or older programming environments may not have the library available.
  • Implementing strcpy without can provide a better understanding of how the function works and improve one's programming skills.
  • It may also be necessary to customize the strcpy function for specific purposes or to improve its efficiency.

3. What are the potential risks of implementing strcpy without ?

The main risk of implementing strcpy without is the potential for errors and bugs. The library is a tested and reliable function, and by implementing it without the library, there is a higher chance of making mistakes or overlooking certain cases. It is important to thoroughly test and debug the code before using it in a production environment.

4. Can strcpy be implemented in other programming languages?

Yes, strcpy can be implemented in other programming languages. However, the implementation may vary depending on the language and its syntax. For example, in C++, the strcpy function is part of the library, while in Python, it is not necessary as strings are immutable and can be easily assigned to another variable.

5. What are some alternative functions to strcpy?

Some alternative functions to strcpy include strncpy, memcpy, and strcat. These functions offer similar functionality, but with some differences. For example, strncpy allows specifying the maximum number of characters to copy, while memcpy copies a specified number of bytes regardless of null terminators. It is important to understand the specific requirements and limitations of each function before using them in code.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
928
  • Engineering and Comp Sci Homework Help
Replies
24
Views
3K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
930
  • Engineering and Comp Sci Homework Help
Replies
1
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
14
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
5
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
11
Views
2K
Back
Top