アプリ版:「スタンプのみでお礼する」機能のリリースについて

C言語でunsigned char配列を連結する方法ってありますか?

例えば
unsigned char test[]={0x00,0x02,0x03};
unsigned char test2[]={0x05,0x06};
という配列があったとして

test[]という配列のあとにtest2の配列を追加することは可能でしょうか?
{0x00,0x02,0x03,0x05,0x06}という配列になればOKです。

よろしくお願いします。

A 回答 (5件)

testの領域は3バイトのため、それ以上の配列を追加することは出来ません。


もし、testのサイズが5バイト以上あれば、test2を追加することは、できます。
その場合は、memcpy(&test[3],test2,2); とすれば、
testの4バイト目からあとに、test2の2バイトが追加されます。
新たに配列を作成して良いなら、
unsigned char test3[5];として
memcpy(test3,test,3);
memcpy(&test3[3],test2,2);
とすれば、test3はtestとtest2を連結したものとなります。

この回答への補足

testのサイズが5バイト以上あればということは
最初にtestを宣言する際にtest[5]という形式にしなくては
ならないということですか?

ちなみにマイコンでバイトを送信するためにunsigned char配列を
用いています。

大きめに領域をとってしまうと
データのないところが0x00となってしまい、送信されてしまうので
望ましくありません。

できるなら決まってunsigned charバイトに追加という形式で
行いたいです。

バイトの追加は複数回行いますので、悩んでいます

補足日時:2010/04/18 12:01
    • good
    • 0
この回答へのお礼

回答を元にAppend関数を作成できました。ありがとうございました。

お礼日時:2010/04/21 10:18

>また送り出すシークエンスの中にデータ長を表すバイトが


>あるため一度すべての配列を一つの配列にまとめて
>しまってlengthを設定したいです。
>イメージとしては大きなシークエンスの中に
>小さなシークエンス(パラメータの一つ)が複数あります。
>この小さなシークエンスの中にもlengthという項目
>があります。

上記の正確な状況は把握できませんが、もしそうであれば、
十分大きな領域を予め確保しておき、そこにデータを格納していけば良いと思います。

送り出すシークエンスの中にデータ長を表すバイトがあると言うことですので、送信する領域のサイズは、実際に送信するサイズと同じである必要はないはずです。(実際に送信するサイズより、同じか大きければよいはずです。データ長を表すバイトで示される長さまでが、実際に送られるので、それ以降は、どのようなデータがあってもかまわないはずです。もちろん、実際に送るべき長さまでは、当然きちんとした値が設定されることが前提です。)
    • good
    • 0

#1です。


>testのサイズが5バイト以上あればということは
>最初にtestを宣言する際にtest[5]という形式にしなくては
>ならないということですか?
はい、その通りです。
最初の質問、そのものが3バイトの領域と2バイトの領域を連結したいということですので、連結した場合は、どうしても最低5バイトは必要になります。
ただ、今回、データを送りたいというのが目的のようですので、対策としては、以下の2つが考えられます。
1案、個々に確保した領域を、個々の領域毎に送り出す。(#2の方の回答)
2案、前もって、送り出す最大のサイズが判っているのなら、そのサイズ分の領域をあらかじめ、確保し、そこへ、送り出すデータをコピーする。
上記の1案も2案もだめだという場合は、もう少し、詳しい事情を、提示していただければ(どのように送信しているか等)、もっと良い対策があるかもしれません。

この回答への補足

返事が遅くなりました。すいません。
今回のデータの送信なのですが
送信するシークエンスが送るたびに異なります。
配列の中のパラメータの数が送る際に異なるため
最初に領域確保が難しいです。
また送り出すシークエンスの中にデータ長を表すバイトが
あるため一度すべての配列を一つの配列にまとめて
しまってlengthを設定したいです。

イメージとしては大きなシークエンスの中に
小さなシークエンス(パラメータの一つ)が複数あります。
この小さなシークエンスの中にもlengthという項目
があります。

個々の小さなシークエンスを一つの関数として戻り値を
unsigned char配列にし、大きな配列を作るときに
個々のunsigned char配列を合体し、その長さを測り
lengthを入力したいです。

うまくニュアンスが伝わらないかもしれませんが
よろしくお願いします。

補足日時:2010/04/19 09:34
    • good
    • 0

マイコンプログラミングはしたことが無いので、メモリーの制約がどの程度あるかしりませんが、自分だったらunsigned charを入れておくデータ型と操作関数を新設しますね。


例えばこんな感じでしょうか。

struct unsigned_string {
unsigned char *data;
unsigned int size;
}

struct unsigned_string*
new_unsigned_string(unsigned char *string, int size)
{
stuct unsigned_string *u;
u = malloc(sizeof(u[0]));
if (u == NULL) {
err(errno, "malloc unsigned_string");
}
u->data = malloc(sizeof(u->data[0])*size);
if (u->data == NULL) {
err(errno, "malloc unsigned_string->data");
}
memmove(u->data, string, size);
u->size = size;

return u;
}

void
destroy_unsigned_string(struct unsigned_string *string)
{
free(string->data);
free(string);
}

void
append_string(struct unsigned_string *string1, struct unsigned_string *string2)
{
unsigned char *tmp;
tmp = realloc(string1->data, sizeof(string1->data[0]) * (string1->size + string2->size));
if (tmp == NULL) {
err(errno, "realloc failed");
}
memmove(tmp+string1->size, string2->data, string2->size);
string1->data = tmp;
}

/* CAUTION: memory is allocated for return value,
* you should free it by yourself.
*/
unsigned char*
get_data(struct unsigned_string *string)
{
unsigned char *ret;
ret = malloc(sizeof(string->data[0]) * string->size);
if (ret == NULL) {
err(errno, "malloc failed");
}
memmove(ret, string->data[0], string->size);
return ret;
}

int
get_size(struct unsigned_string *string)
{
return string->size;
}

unsigned char*
get_data_ptr(struct unsigned_string *string)
{
return string->data;
}

void
trim_last_chars(struct unsigned_string *string, int trim_size)
{
assert (trim_size > 0);
assert (string->size > trim_size);

string->size -= trim_size;
}
    • good
    • 0

すでにあるように、追加するための領域をあらかじめ用意する必要があります。


testに追加するなら test[5]と宣言するとか、追加用の配列を用意するとか、mallocを使うとかです。

> ちなみにマイコンでバイトを送信するためにunsigned char配列を用いています。
>大きめに領域をとってしまうとデータのないところが0x00となってしまい、送信されてしまうので望ましくありません。

どんな方法で送信しているのでしょうか?
送信するバイト数はどうやって決めているのでしょうか?

それによっては
・testを送信して、続けてtest2を送信する
・test[5]等と宣言しても、testだけ送るときは 送信バイト数を3にする
とかの対処方があります。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A