C++ BitStreaming 解码函数返回不良值(指针问题?)

标签 c++ reference operators dereference

我的函数 READ() 似乎工作正常,除了当我转储输入时我得到的比我要求的多。既不是 0 也不是 1 的奇怪字符。我打赌这是由于我的指针使用(取消引用运算符),但我似乎无法弄清楚它在做什么。使其输出正确数据的任何帮助都会有所帮助。此外,一些解释为什么它的错误用法,以及一些关于如何不再这样做的好技巧。谢谢,你们是最棒的。

在 MSVC++ 2010 Express 下编译:

#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;
    }

最佳答案

您将数据保存在 char 数组中,因此当您将它们传递给 std::cout 时,运算符假定以 null 结尾的 C 字符串。除非您的 header 保证以 null 结尾,否则 std::cout 将超出数组的末尾并打印出比您希望的更多的内容。

一种解决此问题的 hacky 方法:

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
};

假设您的编译器没有对 Holder 中的字段重新排序,这应该会导致 std::cout 仅打印您期望的字节数。

这只回答了您问题的一部分。我现在正在发帖,如果我弄清楚其余部分,我会进行编辑。

ETA:查看 READ,您的问题似乎又是缺少空终止。您需要数组中的一个额外字符来保存空字符('\0',几乎普遍等于 NULL,它本身几乎总是 0)这将告诉 std::cout C 字符串正在结束.此外,这是一种向 Holder 提供空终止的更简洁的方法:

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
};

我保留了上面原始的、丑陋的修复程序,因为它说明了导致您的代码打印额外垃圾的规则。

关于C++ BitStreaming 解码函数返回不良值(指针问题?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7671142/

相关文章:

.net - 引用使用旧 .Net 版本构建的 dll

python - 从两侧实现 __rmul__,python

c++ - cuda 数学函数 norm3df 是否溢出?

c++ - 均匀优化(- 1 个值)

c++ - 将在函数中传递引用作为参数以更改参数变量的值。

java - 为什么 println 打印引用对象的值而不是对象的地址

ruby - 在 Ruby 中按多个条件排序

operators - RxJava 在函数中返回订阅值

c++ - 完美转发和 std::forward<T> 的使用

c++ - 多线程的 shared_ptr 销毁是否安全?