0

What's the best way to concatenate unsigned char arrays in C? Furthermore, is there a way to concatenate unsigned char arrays with char arrays? 2 of these unsigned char arrays are really just strings, but for simplicity, I'm treating them as unsigned char arrays.

The requirement is complex: there is a function that will take 1 (one) unsigned char array. That one unsigned char array is really 4 variables concatenated to make up that 1 unsigned char array. To add to the complexity, the first unsigned char array is really just a string of variable length, but its max length is 60 (i.e. sometimes it would have length = 15, other times = 60).

someFunctionAssignsFirst(unsigned char *first) 
{
   //it could be 15 or 60 chars long.
   ...
}

unsigned char first[60] = //someFunctionAssignsFirst() //This is a string i.e. "variable size string max size 60"
unsigned char second[8] = "always8."; //This is a string i.e. "01234567"
unsigned char third[32] = "always32"; //This is a cryptographic key
unsigned char fourth[32] = "always32"; //This is a cryptographic key

How would I go about getting:

unsigned char allstrings[sizeof(first)+sizeof(second)+sizeof(third)+sizeof(fourth)] = //all strings combined

?

I attempted some for loops, but the variable length first is disrupting the concatenation, and I'm sure there has to be a better way.

Full Disclosure: I'm not an expert, and I don't necessarily love C. Also for the requirement, not allowed C++ or any other language.


This is what I was trying to do, and (for clarification) I don't get a null character at the end so it's not really a string.

unsigned char *first = "this is a sample string, human readable";
unsigned char *second = "12345678" //always a number
//unsigned char third -> I have the value from before and it's a key
//unsigned char fourth -> I have the value from before and it's a key
unsigned char allstrings[sizeof(first) + sizeof(second) + sizeof(third) + sizeof(fourth)];
    int counter = 0;
    for (int i = 0; i <= sizeof(first); i++)    
    {
        allstrings[counter] = first[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(second); i++)       
    {
        allstrings[counter] = second[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(third); i++)
    {
        allstrings[counter] = third[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(fourth); i++)
    {
        allstrings[counter] = fourth[i];
        counter++;
    }

The allstrings variable, doesn't get anything beyond "readable" in my example above.

9
  • 1
    To be clear, a character array has a fixed length. It may or may not contain a null character '\0'. A string is a portion of a character array up to and including a null character. So not all character arrays are strings. Commented Feb 18, 2016 at 3:39
  • In what ways this "variable length first is disrupting the concatenation" is happening ? Please post what you have tried . Commented Feb 18, 2016 at 3:41
  • Functions really do not "take 1 (one) unsigned char array". Instead they usually take the address of the first element of the array and the size is also passed in separately. Commented Feb 18, 2016 at 3:43
  • can you clarify that you are not null-terminating second, third,fourth on purpose? Is first null terminated? (if not, how do you know its length) Commented Feb 18, 2016 at 3:47
  • 1
    unsigned char second[8] = "always8."; //This is a string i.e. "01234567" is a contradiction. second[] contains no null character and so cannot be a string. Commented Feb 18, 2016 at 3:49

2 Answers 2

4

You need to use strcpy to copy over the first part, which is a string, then use memcpy to copy over the other 3, which are not strings but char arrays.

Note that the result is not a string but a char array, i.e. it is not null terminated.

unsigned char allstrings[strlen(first)+sizeof(second)+sizeof(third)+sizeof(fourth)];
strcpy(allstrings,first);
memcpy(allstrings+strlen(first),second,sizeof(second));
memcpy(allstrings+strlen(first)+sizeof(second),third,sizeof(third));
memcpy(allstrings+strlen(first)+sizeof(second)+sizeof(third),fourth,sizeof(fourth));
Sign up to request clarification or add additional context in comments.

4 Comments

This might work in some scenarios. My problem is that the function on the other side, needs to have first's length = 60. In this case, even if first is declared as unsigned char first[60] when it gets assigned by a function a value of just 15 chars, the strcpy only writes the 15 chars and on the 16th, begins with second. Thus it will mix the values in the the function accepting my allstrings variable
@dcaping: Arrays in C don't "know" how many elements were stored in them. You will have to keep track of this yourself, in a separate variable, and pass that value to any functions that need to know it.
passing unsigned char array to function expecting char pointer is constraint violation, see here: stackoverflow.com/a/30538279/3963067
This worked with a slight variation. I couldn't get anything beyond readable, and was getting an error. I had to change the char array[] order to put the variable char array last. That was the only way I got it to work. Thanks @dbush
1

I guess you want to treat the array as buffer. So it's fine to have the declarations, but you don't need to define the content for this moment:

unsigned char first[60];
unsigned char second[8];
unsigned char third[32];
unsigned char fourth[32];
#define ALLSTRLEN sizeof(first) + sizeof(second) + sizeof(third) + sizeof(fourth)
unsigned char allstrings[ALLSTRLEN];

The code will keep the fixed size of arrays. and please notice that the arrays should be global or static for safety reasons.

Then you can copy the contents to arrays. I just put your code under main() to concatenate these arrays:

int main()
{
    strcpy((char *)first, "this is a sample string, human readable");
    // do something for second, third, fourth....
    //

    int counter = 0;
    // first array is a normal string, we have to copy null character for it
    for (int i = 0; i <= strlen((char *)first)+1; i++)    
    {
        allstrings[counter] = first[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(second); i++)       
    {
        allstrings[counter] = second[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(third); i++)
    {
        allstrings[counter] = third[i];
        counter++;
    }
    for (int i = 0; i <= sizeof(fourth); i++)
    {
        allstrings[counter] = fourth[i];
        counter++;
    }
    // allstrings is finished
}

Please notice this example just works in main() function; if you call a function to concatenate four arrays, the compiler has to pass the arrays as pointers, and the sizeof() will be wrong (equal to the pointer's size). You can test the size by doing this:

printf("sizeof(second)=%d\n", sizeof(second));

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.