2011-10-06 70 views
0

我的功能READ(),似乎工作正常,除了当我转储输入时,我得到的比我要求的更多。奇怪的字符不是01 s。我敢打赌,这是由于我的指针使用(取消引用操作符),但我似乎无法弄清楚正在做什么。任何帮助使其输出正确的数据将是有帮助的。另外,一些解释为什么它的错误用法,以及一些关于如何不再做的好技巧。谢谢,你们是最棒的。C++ BitStreaming解码函数返回差值(指针问题?)

下MSVC++ 2010速成编译:

#include <iostream> 
using namespace std; 

struct Holder 
{ 
    unsigned char *bits;  // holds our bits 
    unsigned char header[6]; // Always 6 bits 
    unsigned char hasid[1];  // Always 1 bit 
    unsigned char cid[4];  // always 4 bits 
}; 

// Turns our Bytes Into Bits 
// Credit: Ben Voigt(http://stackoverflow.com) 
void BIT(const char *bytes, size_t len, char *bitStr) 
{ 
    while (len--) { 
     bitStr[0] = (*bytes & 0x80) ? '1': '0'; 
     bitStr[1] = (*bytes & 0x40) ? '1': '0'; 
     bitStr[2] = (*bytes & 0x20) ? '1': '0'; 
     bitStr[3] = (*bytes & 0x10) ? '1': '0'; 
     bitStr[4] = (*bytes & 0x08) ? '1': '0'; 
     bitStr[5] = (*bytes & 0x04) ? '1': '0'; 
     bitStr[6] = (*bytes & 0x02) ? '1': '0'; 
     bitStr[7] = (*bytes & 0x01) ? '1': '0'; 
     bitStr += 8; 
     bytes++; 
    } 

    *bitStr = 0; 
} 

// This function is not working correctly 
void READ(unsigned char *BITS, unsigned char *PACKET_ID, unsigned char *HAS_CHANNEL_ID, unsigned char *CHANNEL_ID, unsigned char *PACKET) 
{ 
//===================================================== 
// The Below Header Info Is Always The Same 
//===================================================== 
// Packet ID ALWAYS 6 BITS 
    PACKET_ID[0] = BITS[2]; 
    PACKET_ID[1] = BITS[3]; 
    PACKET_ID[2] = BITS[4]; 
    PACKET_ID[3] = BITS[5]; 
    PACKET_ID[4] = BITS[6]; 
    PACKET_ID[5] = BITS[7]; 

// Packet Has Channel ID (1==true) ALWAYS 1 BIT 
    HAS_CHANNEL_ID[0] = BITS[1]; 

// Channel ID ALWAYS 4 BIT 
    CHANNEL_ID[0] = BITS[0]; 
    CHANNEL_ID[1] = BITS[15]; 
    CHANNEL_ID[2] = BITS[14]; 
    CHANNEL_ID[3] = BITS[13]; 
//===================================================== 
// The above Header Info Is Always The Same 
//===================================================== 
//Variables For Looping 
int P = 16; // This is the start of all data, always 
int B = 24; // Every 24 bits, the loop goes into an IF_STATMENT and reads backwards into the array, then continues normally 
int A = 1; // This Increases every 24 bits 
int Z = 0; // This holds how many times we loop. Used for IF_STATMENT formula 
int I = 0; // This gets zeroed out every IF_STATMENT and keeps our loop int i in sync 
     PACKET[0] = BITS[12]; 
     PACKET[1] = BITS[11]; 
     PACKET[2] = BITS[10]; 
     PACKET[3] = BITS[9]; 
     PACKET[4] = BITS[8]; 

// Starts our main loop... 
for(int i=5 ; i < sizeof(BITS) ; i++, P++, Z++) 
{ 
    PACKET[i] = BITS[P]; 

    if((A * B) == Z) // A==1 B==24 Z==FOR_LOOP 
    { 
     I = 0;  // ZERO THIS OUT. THIS IS USED FOR P COUNTER 
     A++;  // Increase by one for IF_STATMENT formula 
     if((P+7) <= sizeof(BITS)) // if P+7 is less then or equal to BITS then its okay todo the following 
     {       // which is needed because maybe P+7 is bigger then BITS, so this wouldnt be good ... 
      PACKET[i] = BITS[P+7]; 
      I++; 
     } 
     if((P+6) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+1] = BITS[P+6]; 
      I++; 
     } 
     if((P+5) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+2] = BITS[P+5]; 
      I++; 
     } 
     if((P+4) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+3] = BITS[P+4]; 
      I++; 
     } 
     if((P+3) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+4] = BITS[P+3]; 
      I++; 
     } 
     if((P+2) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+5] = BITS[i+2]; 
      I++; 
     } 
     if((P+1) <= sizeof(BITS)) // Explained Above 
     { 
      PACKET[i+6] = BITS[P+1]; 
      I++; 
     } 
     if(P <= sizeof(BITS))  // Explained Above 
     { 
      PACKET[i+7] = BITS[P]; 
      I++; 
     } 
     P += I;     // We have been increasing I each time we do one of the statments to keep track of how many loops 
     if(I != 0)    // we need to add to P to keep it on track ... + I-1 to keep i on track 
      i += I-1; 
    } 
} 
} 

    int main() 
    { 

    const char p40[] = 
    { 
     0x81, 0x11, 0xb6, 0x1e, 0xc9, 0x67, 0x0e, 0x52, 0x0b, 0xec, 0xff, 0x3b, 0xa8, 0xfa, 0x2a, 0x62, 
     0x41, 0x79, 0xd2, 0x75, 0x7b, 0x93, 0xaf, 0xb4, 0xcf, 0x10, 0x3a, 0x12, 0x4d, 0x4b, 0x60, 0x64, 
     0xcc, 0x78, 0x01, 0xd1, 0x83, 0xbc, 0x27 
    }; 

     Holder k;        // Call our struct for holding stuff 
     unsigned char bitbit[sizeof(p40)*8]; // bitbit is an array that is p40 * 8 to get the amount of bits being made using BIT function 

     BIT(p40,sizeof(p40),(char*)bitbit);  // BIT takes p40, and turns it into bits and stores them in bitbit 
     k.bits = bitbit;      // now k.bits is equal to bitbit 

    cout << k.bits;        // dumps k.bits to screen 
    cout << "\n";        // space to see ... 

     unsigned char r[sizeof(k.bits-11)];  // r is k.bits - 11 because 11 bits are used for something else 

     READ(k.bits, k.header,k.hasid, k.cid,r); //This puts k.bits into READ function. Itll store the info into the struct 

    cout << "\nPACKET_HEADER:\n"; 
    cout << k.header;       // This dump seems to be displaying more then what its suppose too... 

    cout << "\nHAS_CANNEL:\n"; 
    cout << k.hasid;       // This dump seems to be displaying more then what its suppose too... 

    cout << "\nCHANNEL_ID:\n"; 
    cout << k.cid;        // This dump seems to be displaying more then what its suppose too... 

    cout << "\nPACKET_BITS:\n"; 
    cout << r;         // The last dump (r) is displaying all inputs into the function READ + r. 

     int a;         // Used to hang program ... 
     cin >> a; 
     return 0; 
    } 

回答

1

你捧在字符数组数据,所以当你把它们传递给std::cout运营者null结束的C字符串。除非你的头文件被保证以空字符结尾,否则std::cout会跑出数组的末尾并打印超过你想要的数值。

A类哈克的方式来解决这个问题:

struct Holder 
{ 
    unsigned char *bits;  // holds our bits 
    unsigned char header[6]; // Always 6 bits 
    unsigned char header_term = '\0' // null terminator 
    unsigned char hasid[1];  // Always 1 bit 
    unsigned char hasid_term = '\0' // null terminator 
    unsigned char cid[4];  // always 4 bits 
    unsigned char cid_term = '\0' // null terminator 
}; 

假设你的编译器不会再为了在持有人的领域,这一点应引起std::cout只打印你所期望的字节数。

这只回答你的问题的一部分。我现在正在发帖,如果我找出其余的话,我会进行编辑。

ETA:查看READ,看起来您的问题再次出现空终止。在数组中需要一个额外的char来保存空字符('\ 0',通常等于NULL,本身几乎总是为0),这将告知std::cout C字符串正在结束。此外,这是提供空终止对持有人提供更清洁的方式:

struct Holder 
{ 
    unsigned char *bits;  // holds our bits 
    unsigned char header[7]={0,0,0,0,0,0,'\0'}; // Always 6 bits 
    unsigned char hasid[2]={0,'\0'};  // Always 1 bit 
    unsigned char cid[5]={0,0,0,0,'\0'};  // always 4 bits 
}; 

我保持高于原来的,丑陋的修复,因为它说明了导致代码打印多余的垃圾的规则。

+0

我明白你的意思了。我为每个值修改了输出:'for(int i = 0; i user954753

+0

sizeof()在编译时计算。因此,对于静态分配的数组,它是数组的大小,但对于指向动态分配数组的指针,它是指针的大小。要么找到一种方法将r的长度从READ传递给main,或者null-terminate。 – 01d55