将十六进制字符输入字符串流

时间:2016-04-01 10:33:18

标签: c++ bit-manipulation

我正在尝试在二进制字符串中设置位。我最初有一个空字符串,需要在字符串中设置给定位(i)。

对于给定的示例,输出应为0x3001 as:

pos: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
bit: 0 0 1 1 0 0 0 0 0 0  0  0  0  0  0  1
     ^                                   ^
     MSB                               LSB

其中,十六进制为3001

#include<iostream>
#include<string>
#include<sstream>
#include<iomanip>

using namespace std;
void generate_string(string& s,int i){
    int sl = s.length();
    int x = i/8;
    std::stringstream m(s, ios_base::app);
    if(sl<x){
        for(int j = x-sl;j>=0;j--){
            m<<'\x00';
        }
    }
    s = m.str();
    s[x] |= 1 << i%8;
}
int main(){
    string s = "";
    generate_string(s,15);
    generate_string(s,2);
    generate_string(s,3);
    for(int i=0;i<s.length();i++)
        cout<<hex<<(int)s[i];
    return 0;
}

但是这个程序没有显示任何输出。

3 个答案:

答案 0 :(得分:1)

它实际上比你想象的要简单得多。唯一复杂的部分是计算要在字节中设置的位数。

哦,为什么要使用字符串呢?为什么不是vector

以下是我的解决方案,改为使用std::vector

void set_bit(std::vector<uint8_t>& bits, unsigned bit)
{
    static unsigned const bit_count = 8;   // Should really use std::numeric_limits<uint8_t>::digits

    unsigned index = bit / bit_count;

    while (index + 1 > bits.size())
        bits.push_back(0);

    // Since the bit-numbers are reversed from what's "common",
    // we need a little more complex calculation here.
    // bit % bit_count to get the "normal" bit number
    // bit_count - bit % bit_count to reverse the bit numbering
    // Then -1 to get a number between 0 and 7
    bits[index] |= 1 << (bit_count - bit % bit_count - 1);
}

可以使用std::string使用类似的解决方案,但我不明白为什么。

答案 1 :(得分:1)

也许是这样的?

#include<iostream>
#include<string>

using namespace std;
void set_bit(string& s,int i){
    auto bits = ((i + 7) / 8) * 8;
    if (bits > s.length())
    {
        auto diff = bits - s.length();
        s += std::string(diff, '0');
    }
    s[i] = '1';
}

int main(){
    string s;
    set_bit(s, 2);
    set_bit(s, 3);
    set_bit(s, 15);
    cout << s << endl;
    return 0;
}

预期产出:

0011000000000001

更新:尝试2: - )

#include<iostream>
#include<iomanip>
#include<string>

using namespace std;
void set_bit(string& s,int i){
    auto bytes = (i + 7) / 8;
    if (bytes > s.length())
    {
        auto diff = bytes - s.length();
        s += std::string(diff, 0);
    }
    s[i / 8] |= char(1 << (7-(i%8)));
}

int main(){
    string s;
    set_bit(s, 2);
    set_bit(s, 3);
    set_bit(s, 15);

    std::cout << "as hex: ";
    for (auto c : s) {
        cout << hex << setfill('0') << setw(2) << (int(c) & 0xff);
    }
    cout << endl;

    std::cout << "as binary: ";
    auto sep = "";
    for (auto c : s) {
        unsigned char bits = c;
        for (unsigned char mask = 0x80 ; mask ; mask >>= 1)
        {
            cout << sep << ((bits & mask) ? '1' : '0');
            sep = " ";
        }
    }
    cout << endl;



    return 0;
}

预期产出:

as hex: 3001
as binary: 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 1

答案 2 :(得分:0)

我不太明白你的问题输出应该是什么,因为你在样本输入/输出中混合了大多数/最少有意义的位和半字节顺序,但是我想以十六进制的形式打印数字作为你可以这样做:

#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>

void feed(std::string& s, int x){
unsigned int mask = 15;
int nibblesInWord = sizeof(void*)*16;
std::stringstream ss;
while(nibblesInWord--){
 std::cout << int(x & mask) <<std::endl;
 ss << int(x & mask);
 x >>= 4;
}
s = ss.str();
std::reverse(s.begin(), s.end());
}


int main(){
std::string s;
 feed(s, 99);
 std::cout << s <<std::endl;
}