• ベストアンサー

バイナリファイルの操作(配列の操作について)

こんにちは。 大変お世話になっております。 配列要素の先頭[0]から[5]までを文字列N、[6]から[1029]までをバイナリデータの計1030バイトの配列要素を使用しています。 [現在行なっている操作方法] 1. Buf[1500]とBuff[1500]を用意 2. fread関数により、Bufに1024バイトずつ格納 3. sprintf関数により、Buffの先頭[0]から[5]まで文字列挿入 4. strcat関数により、BuffとBufを結合 と言う形をとっています。 そこで、sprintfにて先頭から[5]までの文字列を挿入後、先頭から[5]までの配列要素を削除(不要になるため)し、バイナリデータのみにしたいのですが、何か方法はありますでしょうか? NNNNNNDDDDDDDDDDDDDDDDD・・・・・DDDDD←1029番 から NNNNNNを削除し、 DDDDDDD・・・・・DDDDD のみにしたいと思っています。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • clsdi99
  • ベストアンサー率63% (31/49)
回答No.3

普通バイナリーデータをstrcat関数で結合しません。 memmoveやmemcpyなどでデータを移動させます。 ちなみに 2の後に3を行うということは、バイナリ-データの先頭6バイトを上書きしているのですがいいのですか?

bird0214
質問者

お礼

memmoveを利用することで解決することができました。 ありがとうございました。

bird0214
質問者

補足

書き込みありがとうございます。 Buf_1[1500]とBuf_2[1500]を用意しています。(BufとBuffでは区別がつきづらいと思いBuf_1とBuf_2へと表現を変更します) >2の後に3を行うということは、バイナリ-データの先頭6バイトを上書きしているのですがいいのですか? 2. fread関数によって、Buf_1に1024バイトずつバイナリデータを格納 3. sprintf関数によって、Buf_2の先頭[0]から[5]までにテキストデータ(00001(スペース))を挿入 4. strcat(Buf_2,Buf_1)と記述し、 テテテテテテバババババババ・・・・・ババババ テ:テキストデータ バ:バイナリデータ としています。

その他の回答 (2)

回答No.2

関数の意味をよく理解して使用しましょうね。 sprintf strcat はテキストで使用する関数です 関数リファレンスなどを片手に頑張って勉強して下さい。

bird0214
質問者

お礼

ご指摘ありがとうございます。 再度熟慮、してみます。

  • keibou21
  • ベストアンサー率31% (18/58)
回答No.1

memmoveを使用されてはどうでしょうか。

bird0214
質問者

お礼

memmoveにて解決することができました。 ありがとうございました。

関連するQ&A

  • 文字列の操作

    こんにちは。 以下のような、文字列があるとします。 NUMBER1(ヌル\0)からNUMBER1000(ヌル\0)までの文字列があるとします。 NUMBERは付属で、ほしい文字列が1から1000までNUMBERの次にある場合、1から1000までを取得する方法として、 Buf[100] int x=0; while(Buf[x]!='\0') //ナル文字までの長さを取得 x++; memmove(&Buf[0],Buf[x-1],4); //NUMBER1の場合、長さは7。しかしほしい文字列は第6要素なのでx-1。 しかし・・・これを行うと、 NUMBER10:長さ8 NUMBER100:長さ9 ・ ・ となり、二桁以上の場合は、memmove(&Buf[0],Buf[x-2],4)と、 第2引数を手動で可変しなければなりません。 そこで、NUMBER\01\0 NUMBER\01000\0というように、 NUMBERの次にヌル文字(あってますでしょうか?)\0を挿入し、次の要素に1から1000まで文字列を挿入。そして文字列終端が分かるように再度\0を挿入します。 しかしこのような場合、ヌルを2つ挿入することで、上記に示したプログラムでは、手前の\0までしか長さを取得しないので、うまくいきません。 そこで、文字列の区切りを示すための方法として、なにかありますでしょうか? 文字列は最後に、\0を挿入することで判別すると書いてありますが、 NUMBERVISUALC++\0というような文字列を配列に格納してある場合、 NUMBERとVISUALC++をどのように分けて取得するのでしょうか? それとも、第6要素から取得した文字列があると言う事が分かっている場合、第6要素からを指定するプログラムを作るということになるのでしょうか? よろしくお願いします。

  • 抜け落ちている番号を取得する方法(Winsock利用)

    こんにちは。 A→Bというように、 送信端末Aから受信端末Bへパケットを送信する際に、sprintf関数を用いて、各送信パケットに対してナンバリングを行っています。 そして、受信端末において取得することができた番号と抜け落ちている番号を取得したいと思っています。 以下に、プログラムの概要を示します。 [送信側] char send_Buff[1500]; int sequence_Num = 0; //シーケンス番号のカウントアップ sequence_Num++; //sprintf関数にて、文字列格納 sprintf(send_Buff,"%d\0",sequence_Num); sendto関数を使用し、送信 [受信側] recv_Buf[1500]; int x; unsigned int count = 0; recvfrom関数にて送信端末からのパケットを受信し、recv_Bufに格納 count++; //recv_Bufの先頭要素からナル文字までを走査し、ナル文字をみつけたらナル文字の手前の要素までをreceive_seq_Numに格納 for(x=0;recv_Buf[x]!='\0';x++){  receive_seq_Num[count][x] = recv_Buf[x]; } 上記プログラムのように、記述したのですが・・・ [分からない点] 受信側にて、受信することができた各パケットのシーケンス番号のみを配列内に格納したいのですが、上記の記述方法で可能でしょうか? また、配列内に格納したシーケンス番号から抜け落ちているシーケンス番号を割り出したいのですが、どのような記述方法がありますでしょうか? 受信シーケンス番号;1,2,3,4,5,7,10,11,20,21,22・・・ 抜け落ちているシーケンス番号:6,8,9,12,13,14,15,16,17,18,19 ということです。 よろしくお願いします。

  • 配列とポインタについて

    こんばんわ。 WinSockを利用してネットワークプログラミングを行っています。 以下のようなプログラムを作成したのですが、実行できません。 以下のプログラムは質問箇所を抜き出したものです。 [プログラム] int Receive(u_short portNo) { char recv_Buf[1025],recv_Buff[1025]; size = recvfrom(s2, recv_Buf, (int)sizeof(recv_Buf) - 1, 0, (SOCKADDR *)&from, &fromlen); recv_Buff = recv_Buf; Sender(portNo,szServer,recv_Buff); } int Send(unsigned short portNo,char *szServer,char *recv_Buff) { sendto(s1, recv_Buff, (int)strlen(recv_Buff), 0, (LPSOCKADDR)&addrin1, sizeof(addrin1)); } このプログラムは、Receive関数内のrecvfrom関数で1024Byte(recv_Buf[1025])受信したデータをSend関数内のsendto関数で送信するというプログラムです。 recv_Buf = recv_Buffにてエラーが発生します。なにか解決策はりますでしょうか? また、Receive関数およびSend関数は何回も呼ばれるのですが、配列は初期化する必要があるのでしょうか? よろしくお願いします。

  • バイナリファイルとバイナリ文字列の違い

    がわかりません。 例えば >http://e-words.jp/w/E38390E382A4E3838AE383AAE58897.html をみるとバイナリ列は1バイトを連ねたものだというらしいです。 つまり【文】という文字列を文字コードUTF-8でバイト配列化すると [1] => 230 [2] => 150 [3] => 135 となります。 (これはPHPでunpackかけましたが他の言語のGetBytes()などでも同じバイト値がでました。) この【文】という文字列はバイナリ列になるわけですよね? 例えばこの【文】という文字だけを保存したbun.txtというファイルはバイナリーファイルに なるのでしょうか? バイナリファイルの定義をみると >http://e-words.jp/w/E38390E382A4E3838AE383AAE38395E382A1E382A4E383AB.html 上記URLだと >文字コードの範囲などを考慮せずに作成されたファイル というのがバイナリファイルであるとあります。 つまりバイナリファイルとは 1バイト・・つまり8ビット(0~255)までの数値で表したものを連ねたもので なおかつ、文字コードなどの解釈を一切行わなずに、バイト値のみが記述されたデータと おもってもよいのでしょうか?

  • 配列を返す

    ファイルから読み込んだ一行の文字列を読み込みカンマごとに区切って 返すというプログラムを関数化することで効率を図りたいと思います。 int main() { char buf[1000]; char *str; char *bufG; //ファイルを読み込む  while(fgets(buf,1000,fp) != NULL){//一行ずつ読む str = buf;//先頭アドレスを指す     bufG = //文字列を返す関数  ・  ・  ・ } } //文字列を返す関数 {    for(i = 0; *str != ',' && *str != '\0'; i++){ if(*str == '\n'){ bufG[i] = '\0'; } else{ bufG[i] = *str; } str++; } bufG[i] = '\0'; return bufG; } 前の質問で自動変数でこの関数を抜けたら廃棄になるというのは わかったんですが(そういう警告がでました) ここからどのようにすれば求めるプログラムになりますか? 引数とかちょとわからないので関数定義を書きませんでした。 (1)ファイルをよみこむ (2)一行ずつ読み込み文字列をbufにいれる (3)ポインタstrをbufの先頭アドレスにする (4)get_word関数にてポインタをずらしていき カンマがあればそこまでの文字列を返す (5)main関数に戻り変数に代入する (6)終端文字があるまで(4)ー(5)を繰り返す。 (7)さらに行数分繰り返す これらの一連の流れをやりたいのですが わかりません。

  • 配列内に通番(文字列)を挿入したいのですが・・・(Winsock利用)

    こんばんわ。 A端末(送信端末)→B端末(受信端末)というように、A端末から複数パケットを送信し、B端末でパケットを受信するというプログラムをUDPを用いて作成しています。 [実装したいこと] ・A端末において各パケットに対して、通番(TCPのシーケンス番号)のよ うなものを挿入し、パケットを送出。 ・B端末で、どの通番を持つパケットを受信することができたか?を確 認したい。 と思っています。 そこで、上記をふまえ以下のようなプログラムを作成しました。 [A端末(送信側)] //main main(int argc ,char *argv[]){   UDPSending(s_port,szServer); } //whileループにてsend_packet関数を何回も呼び出す。packet_Num変数よりカウントアップ。 UDPSending(unsigned short s_port,char *szServer){  int packet_Num = 1;   while((n = fread(send_Buf,1,SEND_DATA_SIZE,fp)) != 0) {    send_packet(packet_Num, s_port, szServer, send_Buf, n);    packet_Num++;  } } //sprintf関数を使用し各パケットに通番を付加 send_packet(int packet_Num, unsigned short s_port, char *szServer, char *send_Buf, int n){   char send_Buff[1500];   //配列初期化   memset(send_Buff,'\0',sizeof(send_Buff));   //send_Bufに文字列を付加?   sprintf(send_Buf+32,"%d\n",packet_Num);   //send_Bufの内容をsend_Buffへコピー   memcpy(send_Buff,send_Buf,n);   UDPDataSend(s_port, szServer, send_Buff, n); } //パケット送出 UDPDataSend(unsigned short s_port, char *szServer, char *send_Buff, int n){   sendto(省略) } 上記のように、sprintf関数を使用しpacket_Num変数の文字列を挿入することで、送出されるパケットに通番を割り振っていることになるのでしょうか? よろしくお願い致します。

  • 2次元配列への格納方法について

    こんにちは。 FILE *fp; SIZE 1024; int n; char Buf[1025]; while((n = fread(Buf,1,SIZE,fp)) != 0){ } というように、fread関数を用いて1024バイトずつ配列Bufへ格納しています。 以下に示すようなことを行う場合、どのように記述すればよいのでしょうか? B:バイナリデータ T:数値 TBBBBBBBBB・・・・・・B←1024バイト目 TBBBBBBBBB・・・・・・B ・ ・ ・ ・ TBBBBBBBBB・・・・・・B というように、配列内に格納したいと思っています。 Tは、テキストデータで1,2,3・・・・100という整数型を格納。Bは、バイナリデータでfread関数から取得したバイナリデータを格納します。 なぜ、Tを格納したいかといいますと、どのバイナリデータを指しているか?を判別するためです。 上記のようなことを行うためには、2次元配列を使用すればよいのでしょうか? 例:char Buffer[100][1025]

  • 連想配列のソート

    次のような連想配列があります。 $buff[0][0]=1; $buff[0][1]=567; $buff[0][2]=134; $buff[0][3]="文字列"; $buff[1][0]=2; $buff[1][1]=246; $buff[1][2]=537; $buff[1][3]="文字列"; $buff[2][0]=3; $buff[2][1]=897; $buff[2][2]=334; $buff[2][3]="文字列"; ~ 要するに キー,数字,数字,文字列 が並んでいて、キーと値を保持したまま真ん中の数字二つを使ってソートしたいのですが、どのようにすればいいでしょうか。 asort($buff[1], SORT_NUMERIC); reset ($buff[2]); asort($buff[2], SORT_NUMERIC); reset ($buff[2]); のように試してみたのですが、まったく並びは変わりませんでした。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • sprintf関数での文字列変換について

    マイコンにて、 C言語で浮動小数点の数値を表示するプログラムを作成しているのですが、 PRINT_OUT("123.456"); のように、文字列を直接指定した場合は正しく表示されるのですが、 sprintf()関数を用いて、浮動小数点を文字列に変換した場合、 buf char[10]; sprintf(buf,"%lf",123.456); PRINT_OUT(buf); とした場合はプログラムが暴走?(恐らく配列破壊を起こしていると 思われますが、)してしまい、上手く動作しません。 (但し、整数の場合は正常に動作します。) そこで、質問させていただきたいのですが、 "123.456"のように直接文字列を指定した場合と、浮動小数点123.456 をsprintf()関数を用いて文字列に変換した"123.456"の書式に何か 違いはあるのでしょうか?よろしくお願い致します。

  • ポインタの配列について

    はじめまして。 基本的な質問で恐縮ですが、質問があります。 例えば、char *name[] = {"Alice","Ben","Chris","Diana","Elmo"} のようなポインタの配列を宣言・初期化したとき、配列nameの各要素の 中身には、初期化子として与えた、文字列の先頭アドレスが 格納されているという解釈でよろしいのでしょうか?つまり、 *(name+1)やname[1]は、「文字列Benの先頭アドレスを指す」という意 味でよろしいのでしょうか?また、このとき、(name+1)というように *をつけないときは、「文字列Benの先頭アドレスを格納したメモリの 先頭アドレス」というような解釈でよろしいのでしょうか? どうかご教授お願いします。

専門家に質問してみよう