1

バイナリメッセージを作成するプログラムを作成しています。バイナリ値を保持するためにchar文字列を使用しています。そこで、デフォルト値を持つ一連のchar文字列を初期化しました。次に、forループを実行してそれらを結合し、大きな文字列(aismsg / ais_packet)に読み込みます。そして、msg14Text []を追加するまではすべて正常に機能しました。その後、作成している文字列(aismsg / ais_packet)は、以下に示すように短縮されます(変数を使用していなくても)。msg14Text []を追加すると、他の文字列の1つの値が変更されるようです。これはおそらくメモリ割り当ての問題ですか?

コードの一部:

char ais_packet[257];                           //Allokerer array for ais data pakke.
char aismsg[175];                               //Allokerer array for meldingen.
int burst_nr = 1;                               //Indicates with burst it is transmittin (1-7).

char ramp_up[] = "00000000";                    //Ramp up buffer.
char train_seq[] = "010101010101010101010101";  //Training sequence 24 bits of alternating 0-1.s
char hdlc_flag[] = "01111110";                  //HDLC Start and END flag.
char buffer[] = "000000000000000000000000";     //Data packet buffer.
char msgID1[] = "000001";                       //msg. 1.
char msgID14[] ="010100";                       //msg. 14.
char repeat[] = "00";                           //repetert 0 ganger.
char mmsi[] = "000111010110111100110100010101"; //Gir 123456789  som MMSI.
char nav_stat[] = "1111";                       //Gir 15= AIS-SART test, endres til 14 (1110) for aktiv AIS-SART.x'
char rot[] = "10000000";                        //Rate of Turn -128 betyr ikkje tilgjengelig.
char sogBin[] = "1111111111";                   //Tilsvarer 1023 = not available = default.
char pos_acc[] = "0";                           //Posisjonsnøyaktighet over 10m. 1 = under 10m.
char lonBin[] = "0110011110010001101011000000"; // Tilsvarer 181 grader som er default verdi for Longitude.
char latBin[] = "011010000010010000101000000";  // Tilsvarer 91 grader som er default verdi for Latitude.
char cogBin[] = "111000010000";                 //Tilsvarer 3600 = not available = default.
char headingBin[] = "111111111";                //511 = not available = default
char timestamp[] = "111100";                    //Tid siden melding er generert, 60 = default = ts not available.
char spec_man[] = "01";                         //Special manouver 0 = default, 1 = not engaged in special manouver
char spare[] = "000";
char spareMSG14[] = "00";                           //Reserved.
char raim[] = "0";                              //RAIM 0 = not in use.
char comm_state[] = "00011100000000000000";     // First 2bit: Sync state: 3 = no UTC sync = default, 0 = UTC sync. 0011100000000000000
char msg14Text[] = "100100101101111011111100";  //CAUSING TROUBLE!!!!  for AIS melding 14 står "Test" med 6-bit ASCII koding.

関数の全体のコードは、pastebin.com/wj0RxyLXにあります

msg14Text []を使用したaisパケットの出力:

00000000

msg14Text []なしのaisパケットの出力:

0000000001010101010101010101010101111110000001000001110101101111001101000101011111100000000011010000000000000110100011000101111000000101100100000100001100101110000100000000110011111000100000011100000000000000001000100110100101111110000000000000000000000000

aispacketは、次の変数で構成されている必要があります。

ramp_up[] + train_seq[] + hdlc_flag[] + Datapacket(168bit) + crc(16bit) + hdlc_flag[] + buffer[] + '\0'
4

3 に答える 3

1

「これはおそらくメモリ割り当ての問題ですか?」

コードにメモリを明示的に割り当てることはありません。char repeat[] = "00";サイズが3秒のサイズに等しくchar、内容が文字列リテラルによって初期化されている静的に割り当てられた配列であることに注意してください"00"

これらの文字列をにコピーする際に問題が発生する可能性が最も高くなりais_packetます。これは、コードを読みにくく、間違いを犯しやすい非標準的な方法(文字ごと)で行うためです。

for(int k=0; k<256; k++)
{
    ...
    if(k==256) // are you sure that value of k will reach 256 ?

この目的のために作成されたCスタイルの関数を使用することをお勧めします。Craeteais_packetを使用して最初の文字列をコピーし、を使用して他の文字列を追加してstrcpyこのコンテンツを拡張し続けます。ais_packetstrcat

この質問はあなたにも役立ちます:Cでstrcatを使用する

于 2012-05-24T10:03:14.443 に答える
1

醜いfor (k=0; k < 168; k++) { if ... else if ...}ループの果てに

else if(k==168)
      {
        aismsg[k] = '\0';
        k=0;
      }

これにより、(k <=168) ループが永久に実行されるか、(k <168) 実行されなくなります。(このパターンは他にもあります)

ところで、同じことを行う別の方法(これも高速)は次のとおりです。

....
unsigned dst=0;
memcpy (array+dst, src1, 123);
dst += 123;
memcpy(array+dst, src2, 234);
dst += 234;
...
array[dst] = 0;
于 2012-05-24T11:36:48.090 に答える
0

考えただけですが、バイナリ メッセージを作成している場合は、char 配列の代わりに実際のバイナリを使用してみませんか? ユニオン内で構造体を使用してバイナリ データをビットパックする方法を次に示します。

// declaration
typedef union
{
     uint32_t packed;
     struct {
         uint16_t  sample1: 12;  // 12 bits long
         uint16_t  sample2: 14;  
             uint16_t  6;            // unused bits
     } data;
} u1;

// instantiation
u1 pack1;

// setting
pack1.data.sample1 = 1234;
//getting
uint16_t newval = pack1.data.sample2;
// setting bit 6 in sample 1
pack1.data.sample1 |= (1 << 6);
// setting lo nibble in sample1 to 0101
pack1.data.sample1 &= 0b11110101;
// getting the whole packed value
uint32_t binmsg = pack1.packed;
于 2012-07-17T16:33:52.973 に答える