简体   繁体   中英

pointers strings

to copy at the correct place but doesn't stop after the count is reached. I thought my code should work as follows

char har *orig, int start, int count, char *final);

int main(void)
{
    const char source[] = "one two three";
    char result[] = "123456789012345678";

    printf("%s\n",GetSubstring(source, 4, 3, result));

    return 0;
}

char r *orig, int start, int count, char *final)
{    
    char *temp = (char *)orig;

    final = temp;


   }

    for ( ; *temp && (count > 0) ; count--)
    {
    rn final;
}
  1. The first for loop doesn't check if temp array exists (how would it check for existence of an allocated memory without asking memory manager in some way?!). The temp is merely a pointer. What you're checking for is that the orig string doesn't have a zero within the first start bytes. That's OK, perhaps' that's what you meant by "existence".

  2. Your intention is to copy from orig to final , yet you reset final to orig . That's where your error is. You must remove that line and it fixes the problem.

  3. You don't need to create the temp pointer, you can use the orig pointer. You're free to modify it -- remember, function arguments are in effects local variables. Function arguments in C are pass-by-value, you implement pass-by-reference by passing pointers (which are values!) to data.

I should add perhaps that the premise of this function is somewhat broken. It "works", but it's not what one might reasonably expect. Notably:

  1. There's no indication that the source string was shorter than start .

  2. There's no indication that the source string was shorter than start + count .

    Perhaps those are OK, but in cases where those conditions could be an error, it should be possible for the user of the function to get an indication of it. The caller would know what's expected and what's not, so the caller can determine it if only you'd provide some feedback to the caller .

  3. You're returning the position that's one past the end of the output -- past the zero-termination. That's not very convenient. If one were to use the returned value to concatenate a subsequent string, it'd have to be decremented by one first.

Below is the fixed code, with sanely named variables.

char *GetSub(const char *src, int start, int count, char *dst)
{
    for ( ; *src && (start > 0) ; start--)
    {
        src++; /* Note: *src++ works too, but is pointless */
    }

    for ( ; *src && (count > 0) ; count--)
    {
        *dst++ = *src++;
    }

    *dst++ = 0;
    return dst; /* Notice: This returns a pointer to the end of the
                memory block you just wrote. Is this intentional? */
}

There are several problems in what you have written. Let's enumerate:

  1. char *temp = (char *)orig; - You're assigning a const char * (you promise not to modify) to a char * (you break that promise). Wrong thing to be doing.

  2. final = temp . No this does not make the original final (the copy held by the caller) change at all. It achieves nothing. It changes your (function's) copy of final to point to the same place that temp is pointing.

  3. *temp++; - There's no point de-referencing it if you're not going to use it. Incrementing it of course, is correct [see comment thread with KubaOber below].

  4. final++ = *temp++; - This is just confusing to read.

  5. *final++ = 0; return final; - You're setting the value at the address final to '0'. Then you're incrementing it (to point to somewhere in space, maybe towards a black hole). Then returning that pointer. Which is also wrong.

What you really should do is to wrap strncpy in a convenient way.

But if you insist to write your own, you'd probably want your function to be something as simple as:

char *GetSub(const char *orig, int start, int count, char *final)
{    
  int i;

  for (i = 0; i < count; i++)
    {
      final[i] = orig[i+start];

      if (final[i] == '\0')
        break;
    }
  final[i] = '\0';

  return final; /* Yes, we just return what we got.  */
}

The problem is with the following line:

final = temp;

Remove it, and the problem should be resolved.

char *a="abcdefgh";

i want string "cde" to be copied into another.

index i got is 3(your start).

char *temp=malloc(3*sizeof(char))
strncpy(temp,a+3,3);

is this what you need?

Change your GetSub function:

char *GetSub(const char *orig, int start, int count, char *final)
{
    char *temp = (char *)orig;

    // with original final = temp and final++ you loose final valid pointer
    char *final2 = final;


    for ( ; *temp && (start > 0) ; )
    {
        start--;

        // you don't need to dereference temp
        temp++;
    }

    for ( ; *temp && (count > 0) ; count--)
    {
        *final2++ = *temp++;
    }

    *final2 = 0;

    // return a valid pointer
    return final;
}

you have some mistakes on your code :

char *GetSub(const char *orig, int start, int count, char *final)
{
    char *temp = (char *)orig;

    //final = temp; /* Why this? */

    for ( ; *temp && (start > 0) ; )
    {
        start--;
        temp++; /* Instead of *temp++ */
    }

    for ( ; *temp && (count > 0) ; count--)
    {
        *final++ = *temp++;
    }

    *(final+count) = '\0';
    return final;
}

Hope this help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM