I have a system that needs a 7 bit character string converted to an 8 bit string of binary ones and zeroes, in this fasion:

My main task is to find a way of generating a boolean array of each character and its corresponding 7 bits in order to do manipulations on them. ideally this would have the text string passed as a parameter to the program. I have searched a number of places for this sort of setup but no-one has any great ideas, can you help?

Dani AI

Generated

Short version: decide whether you want (A) a per-character 7-bit boolean representation (one septet per input char) or (B) the packed, contiguous stream of 7-bit characters stored into 8-bit octets (the GSM-style “septet packing” your linked example shows). was on the right track using unsigned data and bit ops, but his example extracts 8 bits per char and shifts the original buffer (losing the original characters) and emits LSB-first bit order — which may not match your target format.

To get a clean, non-destructive septet for each input character, mask the low 7 bits and store them as a small bitset. This preserves the original string, makes bit-order explicit, and is easy to convert to booleans or printable "0"/"1" later:

#include <bitset>
#include <string>
#include <vector>

std::vector<std::bitset<7>> septets_from(const std::string& s) {
    std::vector<std::bitset<7>> out;
    out.reserve(s.size());
    for (unsigned char c : s)
        out.emplace_back(static_cast<unsigned long>(c & 0x7F));
    return out;
}

If you need the packed 7->8 bit stream (bytes that contain bits from multiple characters), use a small bit-buffer accumulator. This implements the usual septet packing (LSB-first across output bytes):

#include <string>
#include <cstdint>

std::string pack_gsm7(const std::string& s) {
    std::string out;
    uint32_t bitbuf = 0;
    int bitcount = 0;
    for (unsigned char c : s) {
        uint8_t septet = c & 0x7F;
        bitbuf |= (uint32_t(septet) << bitcount);
        bitcount += 7;
        while (bitcount >= 8) {
            out.push_back(char(bitbuf & 0xFF));
            bitbuf >>= 8;
            bitcount -= 8;
        }
    }
    if (bitcount) out.push_back(char(bitbuf & 0xFF));
    return out;
}

Troubleshooting notes: always treat characters as unsigned when masking (avoid sign extension), pick MSB-or-LSB-first consistently to match the receiver, and unit-test with known samples (for example the "HELLO" example from the original post). Avoid std::vector<bool> for packed storage unless you understand its specialization quirks; use std::string or std::vector<uint8_t> for raw bytes.

Recommended Answers

All 3 Replies

From what I understand, an 'unsigned char' datatype will give you straight-up binary properties.. 8 bits, 1 byte, 0 to 255.

My main task is to find a way of generating a boolean array of each character

I think a pseudo-code for the task at hand could be this:

1. create an unsigned char c-string of desired characters

unsigned char cstring[5] = {'H', 'E', 'L', 'L', 'O', '\0'};

2. create a bool array that will equal (n*8) the size of your unsigned c-string

//5 characters, 8 'bits' per character (no need to account for null terminating character)
bool binary[5][8];

3. perform bit shifting and extraction on individual c-string elements in order to populate 8 elements of the bool array

//haven't done bit shifting/extraction in awhile, hope this is right
for(int i=0; i<5; i++)
{
     for(int j=0; j<8; j++)
     {
          //extract right-most bit
          cstring[i] & 1 = binary[i][j];
          //shift all bits right one place
          cstring[i] >> 1;
     }
}

4. you now have the bool array populated with the equivalent binary representation of ascii characters, feel free to make any additional bitwise operations you need.

I guess this should be:

unsigned char cstring[6] = {'H', 'E', 'L', 'L', 'O', '\0'};

Here is working code that compiles, runs, and tests good:

#include<iostream>
using namespace std;

int main()
{
    unsigned char cstring[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
    bool binary[5][8];

    for(int i=0; i<5; i++)
    {
        cout << endl << cstring[i] << '\t' << (int)cstring[i] << '\t';

        for(int j=0; j<8; j++)
        {
            binary[i][j] = cstring[i] & 1;
            cstring[i] >>= 1;
            cout << binary[i][j];
        }
    }

    return 0;
}
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.