我正在制作一个构建二进制消息的程序。我使用char字符串来保存二进制值。所以我已经初始化了一堆具有默认值的char字符串。然后我通过运行for循环将它们组合起来并将它们读成一个大字符串(aismsg / ais_packet)。一切正常,直到我添加msg14Text [],然后我建立的字符串(aismsg / ais_packet)缩短,如下所示(即使我没有使用变量)。好像当我添加msg14Text []时,它会更改其他字符串之一的值。这可能是内存分配问题吗?
部分代码:
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.
该功能的enitre代码可在pastebin.com/wj0RxyLX
找到使用msg14Text []输出ais数据包:
00000000
没有msg14Text []的ais数据包的输出:
0000000001010101010101010101010101111110000001000001110101101111001101000101011111100000000011010000000000000110100011000101111000000101100100000100001100101110000100000000110011111000100000011100000000000000001000100110100101111110000000000000000000000000
aispacket应包含以下变量:
ramp_up[] + train_seq[] + hdlc_flag[] + Datapacket(168bit) + crc(16bit) + hdlc_flag[] + buffer[] + '\0'
答案 0 :(得分:1)
“这可能是内存分配问题吗?”
您没有在代码中明确分配任何内存。请注意char repeat[] = "00";
是静态分配的数组,其大小等于3 char
s的大小,其内容由字符串文字"00"
初始化。
问题最有可能是将这些字符串复制到ais_packet
,因为你以非标准的方式(逐个字符)这样做会导致你的代码难以阅读而且很容易在那里犯错:< / p>
for(int k=0; k<256; k++)
{
...
if(k==256) // are you sure that value of k will reach 256 ?
我建议您使用为此目的创建的C风格函数:通过使用ais_packet
将第一个字符串复制到其中来克隆strcpy
并继续扩展此ais_packet
的内容通过使用strcat
附加其他字符串。
此问题也可以帮助您:Using strcat in C
答案 1 :(得分:1)
在丑陋的for (k=0; k < 168; k++) { if ... else if ...}
循环结束时
else if(k==168)
{
aismsg[k] = '\0';
k=0;
}
这将使(k <= 168)循环永远运行,或者(k <168)永远不会被执行。 (这种模式的实例更多)
BTW另一种做同样的事情(也更快)将是
....
unsigned dst=0;
memcpy (array+dst, src1, 123);
dst += 123;
memcpy(array+dst, src2, 234);
dst += 234;
...
array[dst] = 0;
答案 2 :(得分: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;