5

I have a char buf[x], int s and void* data.

I want to write a string of size s into data from buf.

How can I accomplish it?

Thanks in advance.

2
  • 2
    Is buf a null-delimited string or is its size defined by s? Are you trying to copy just a part of the string? What is x? Does the string copied to data need to be null-delimited? What have you tried so far? Commented Jul 18, 2010 at 15:54
  • note that caf pointed out several mistakes in my answer. I've edited my answer to take his comments into account. Commented Jul 19, 2010 at 17:33

5 Answers 5

5

Assuming that

  • by “string” you mean a null-terminated string as is normally meant in C;
  • you haven't yet allocated memory in data;
  • you already know that s <= x

First you need to allocate memory in data. Don't forget the room for the 0 byte at the end of the string.

data = malloc(s+1);
if (data == NULL) {
    ... /*out-of-memory handler*/
}

Assuming malloc succeeds, you can now copy the bytes.

EDIT:

The best function for the job, as pointed out by caf, is strncat. (It's fully portable, being part of C89.) It appends to the destination string, so arrange for the destination to be an empty string beforehand:

*(char*)data = 0;
strncat(data, buf, s);

Other inferior possibilities, kept here to serve as examples of related functions:

  • If you have strlcpy (which is not standard C but is common on modern Unix systems; there are public domain implementations floating around):

    strlcpy(data, buf, s+1);
    
  • If you know that there are at least s characters in the source string, you can use memcpy:

    memcpy(data, buf, s);
    

    ((char*)data)[s+1] = 0;

  • Otherwise you can compute the length of the source string first:

    size_t bytes_to_copy = strlen(buf);
    if (bytes_to_copy > s) bytes_to_copy = s;
    memcpy(data, buf, bytes_to_copy);
    ((char*)data)[s+1] = 0;
    
  • Or you can use strncpy, though it's inefficient if the actual length of the source string is much smaller than s:

    strncpy(data, buf, s);
    ((char*)data)[s+1] = 0;
    
Sign up to request clarification or add additional context in comments.

2 Comments

Your memcpy() implementations have bugs - they both place the nul terminator incorrectly, and they try to dereference a void *, which you can't do. The first should use ((char *)data)[s] = 0, and the second should use ((char *)data)[bytes_to_copy] = 0;. For the last one, instead of strncpy() you can use strncat(): ((char *)data)[0] = 0; strncat(data, buf, s);
@caf: you're right on both counts. Unfortunately my answer has been accepted, so I've edited it rather than delete it because I don't want to leave a wrong answer too visible. But if you write an strncat answer, I'll upvote it.
3

If data is not allocated:

char buf[] = "mybuffer";
void *data = malloc(strlen(buf)+1);
strcpy((char*)data,buf);

Actually if data is really to be defined you can also do

char buf[] = "mybuffer";
void *data= (void*)strdup(buf);

3 Comments

You should malloc(strlen(buf)+1)
Yes, and here buf is null-terminated even though it isn't a string literal. But strlen(buf) doesn't include the terminator byte in its count.
You could use sizeof buf instead of strlen(buf)+1 here since buf is an array.
2
memcpy(data, buf, s);

This assumes that you have enough space in data (and in buf).

Depending on what you are doing (you don't say, but you do say that you are copying strings), you may want to add a null at the end of your newly copied string if you did not copy a null already in buff, and you are going to use data in a function that expects strings.

Comments

2
data = malloc(s);
strcpy((char*)data,buf);
free(data);

Comments

2
int n = MIN((x - 1), s);
char *bp = buf;
char *dp = (char *)data;
while (n--) {
  *bp++ = *dp++;
}
*dp = '\0';

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.