2016-04-01 57 views
0

我试图在二进制字符串中设置位。我最初有一个空字符串,需要在字符串中设置给定位(i)。将十六进制字符输入到字符串流

对于给定的例子中,输出应该是0x3001为:

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

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

+0

首先,你确实是知道比特数字实际上是相反的方式?位0是二进制数中的第一位(最低位),位15是16位二进制数中的最后位(最高位)。其次,您应该学会如何使用调试器,以便您可以自己完成代码。 –

+0

你想让程序做什么?将位号对应的字符串设置为1? –

+0

@JoachimPileborg我需要这样实现它。而且我知道这些位是相反的。我想你是说我需要把s [x] | = 1 << i%8;'改成's [x] | = 1 <<(7-(i%8));'' 。我试图得到[这](http://stackoverflow.com/questions/20673131/can-someone-explain-redis-setbit-command)种行为。学习使用调试器就在我的列表中。 – ayushgp

回答

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

也许这样吗?

#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 
+0

如上图所示,这不是预期的输出结果,如果将该二进制数翻译为十六进制数,它绝对不是“0x3001”。 –

+0

哎呀 - 斑点。修复了逻辑错误 –

+0

这是使用16个字节。这是我不想要的东西。我试图实现的是只使用2个字节来存储信息。 – ayushgp

0

我不太明白输出应该在你的问题中,因为你在混合大多数/ leas在样品输入/输出半字节顺序牛逼signifanct位,但我愿你在十六进制数字印刷作为一个字符串可以做某事像这样:

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

我编辑了预期的输入/输出。这个程序的输出是什么? – ayushgp

+0

在64位机器上0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063,您可以摆脱领先的0,并将63 – user3655463

相关问题