0

I have to write strcpy() and strcat() in 7 lines of code and deal with any exceptions there could be. This is my code so far. Does anyone have any suggestions on how I can reduce the number of lines?

char *mystrcpy(char *dst, const char *src)
{
    char *ptr;
    ptr = dst;
    while(*dst++=*src++);
    return(ptr);
}

void strcat(char *dest, const char *src)
{

    while (*dest!= '\0')
        *dest++ ;
    do
    {
        *dest++ = *src++;
    }
    while (src != '\0') ;
}
Uyghur Lives Matter
  • 18,820
  • 42
  • 108
  • 144
  • 5
    You can write it on one line if you want ... – Martin R Dec 09 '13 at 16:02
  • If it seems to work, then this should go to codereview.stackexchange.com. So, does the code work? If not what issues do you face, please? – alk Dec 09 '13 at 16:05
  • @alk You must not have looked at it. It's got some serious problems. – Fiddling Bits Dec 09 '13 at 16:07
  • Did you really try this on some test cases? I'd focus on getting it right before getting it short. – Andrey Mishchenko Dec 09 '13 at 16:12
  • @user3082112 Before you write your own implementation you need to know this first: can `dst` and `src` overlap? – Fiddling Bits Dec 09 '13 at 16:12
  • @BitFiddlingCodeMonkey: No. The standard `strcpy` and `strcat` functions have undefined behavior if the source and destination overlap. Which means that, as an implementer, you don't have to worry about it. – Keith Thompson Dec 09 '13 at 16:19
  • @KeithThompson I believe you use the keyword `restrict` in that case. – Fiddling Bits Dec 09 '13 at 16:21
  • @BitFiddlingCodeMonkey: I wrote "*If it seems to work, then ....*", as the OP did not mentioned any issues, I also did not referr to any. – alk Dec 09 '13 at 16:51
  • @BitFiddlingCodeMonkey: The standard declarations for `strcpy` and `strcat` do use `restrict`. The standard *also* explicitly says that the behavior is undefined if the source and target overlap. – Keith Thompson Dec 09 '13 at 16:52

2 Answers2

1

You have a problem with your code: you are testing src itself against '\0', and not the char it is pointing to.

while (src != '\0');

should be

while (*src != '\0');

First get it right, then get it short / fast.


You are writing about being exception safe all over this page. Since you are using C, there is no native language concept like exceptions (as opposed to C++).

Anyway, the only type of exceptions that your code could raise are hardware exceptions (page fault, stack fault, alignment check, ...) which can't be caught by a normal C++ try-catch. Since the handling of hardware exceptions is platform dependent, you would need to use a platform specific mechanism to catch them (like SEH for Windows, or a signal handler for Unix). This approach is nothing I would recommended, read on.

Much better than catching a hardware exception is to try as hard as you can to prevent it. In your code this would just mean testing the input pointers for != 0. Note that you have no chance to identify an invalid pointer like char* dst = 0xDEADBEEF; and the only way to handle the exception after it was accessed would be platform dependent code like mentioned above. But hard errors like this typically shouldn't be handled by your program at all.

Example:

// Returns the new string length, or -1 on error.
int strcat(char* dst, char const* src)
{
    // Check arguments before doing anything.
    if (dst == 0)
        return -1;
    if (src == 0)
        return -1;

    // Store begin of destination to compute length later on.
    char const* const dstBegin = dst;

    // Skip to end of destination.
    while (*dst != '\0')
        *dst++ ;

    // Copy source to destination.
    do
    {
        *dst++ = *src++;
    }
    while (*src != '\0');

    // Return new length of string (excluding terminating '\0').
    return (dst - dstBegin - 1);
}

Optionally you could introduce a dstSize parameter which would indicate the size of the destination buffer, so that you could effectively detect and prevent buffer overflows.

Max Truxa
  • 3,308
  • 25
  • 38
  • ok i correct it . but what can i do to confirm that the func works and return output for every input that i will except even for exceptions? someone can help?Thanks – user3082112 Dec 09 '13 at 16:47
  • Why would the input be invalid when the destination is stored at a lower address? – Max Truxa Dec 09 '13 at 20:08
1
char *mystrcpy(char *dst, const char *src){
    return (*dst=*src) ? (mystrcpy(dst+1, src+1), dst) : dst;
}
char *mystrcat(char *dst, const char *src){
    return (*dst ? mystrcat(dst+1, src) : mystrcpy(dst, src)), dst;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • @BitFiddlingCodeMonkey it must be assigned. because it is necessary to perform the copy. – BLUEPIXY Dec 09 '13 at 17:05
  • but how can i deal with exceptions that could be? – user3082112 Dec 09 '13 at 17:51
  • @user3082112 Better error handling conflicting, to reduce code. – BLUEPIXY Dec 09 '13 at 17:59
  • yes but there is no exception in c.how can i implement exception in c? – user3082112 Dec 09 '13 at 20:50
  • @user3082112 I think it's going to be things like preventing the normal pre-exception because it is not supported in C. you say absolutely, I think it will be such as a built-in interpreter. Consider what you can do for the execution of expressions such as E.g ` x = 1/0;`. – BLUEPIXY Dec 09 '13 at 21:09
  • It is not possible to error handling when passed the memory of the write-protect Speaking in `strcpy`. – BLUEPIXY Dec 10 '13 at 08:40