簡體   English   中英

二進制char數組到stringstream並從緩沖區彈出

[英]Binary char array into stringstream and pop from the buffer

我有20byte二進制字符數組。 我想分成3個部分:4byte,8byte,8byte。 我實現了如下所示。 它工作但似乎我可能能夠使用緩沖流。 我想知道如何使用它。

現在

void main()
{
    // _data is 20byte binary char array. 0000000000000000000000000000000000000000000001111001110001111111001110000010110000001011101101000000000000000000000000000000000000000000000000000000000000000001

    // strA (4 byte)
    string strA;
    for (std::size_t i = 0; i < 4; ++i) {
        strA += bitset<8>(_data.c_str()[i]).to_string();
    }

    cout << strA << endl; // 00000000000000000000000000000000

    // strB (8 byte)
    string strB;
    for (std::size_t i = 4; i < 12; ++i) {
        strB += bitset<8>(_data.c_str()[i]).to_string();
    }

    cout << strB << endl; // 0000000000000111100111000111111100111000001011000000101110110100

    // strC (8 byte)
    string strC;
    for (std::size_t i = 12; i < 20; ++i) {
        strC += bitset<8>(_data.c_str()[i]).to_string();
    }

    cout << strC << endl; // 0000000000000000000000000000000000000000000000000000000000000001
}

期望

我想這樣實現。

void main()
{
    stringstream ss = _data;
    strA = ss.pop(4);
    strB = ss.pop(8);
    strC = ss.pop(8);
}

更新1

感謝大伙們。 我正在嘗試你一個接一個給我的所有答案。 我是c ++的新手所以需要時間來理解它。 以下是Anders K的一個。

struct S { char four[4]; char eight1[8]; char eight2[8]; }; 
struct S *p = reinterpret_cast<S*>(&_data); 
cout << p->four << endl; // => Output "(" I think I can find way to output

更新2

它使用string :: substr。 謝謝Zakir。

int main()
{
    // I don't know how to change to string value in smart way.. 
    string str;
    for (std::size_t i = 0; i < _data.size(); ++i) {
        str += bitset<8>(_data.c_str()[i]).to_string();
    }

    cout << str << endl; // 0000000000000000000000000000000000000000000001111001110001111111001110000010110000001011101101000000000000000000000000000000000000000000000000000000000000000001

    std::string d = str; // Your binary stream goes here
    int lenA = (4*8);  // First  4 Bytes
    int lenB = (8*8);  // Second 8 Bytes
    int lenC = (8*8);  // Last   8 Bytes

    std::string strA = d.substr(0,    lenA);
    std::string strB = d.substr(lenA + 1, lenB - 1);
    std::string strC = d.substr(lenA + lenB + 1, lenC - 1);

    cout << strA << endl; // 00000000000000000000000000000000
    cout << strB << endl; // 000000000000111100111000111111100111000001011000000101110110100
    cout << strC << endl; // 000000000000000000000000000000000000000000000000000000000000001
}

更新3

當我嘗試Scheff時,我遇到了一個錯誤。 這是我的錯,我想我可以解決它。 我想我應該重新考慮_data的類型。

int main
{
    const char data = _data;
    const char *iter = data;
    string strA = pop(iter, 4);
    string strB = pop(iter, 8);
    string strC = pop(iter, 8);
    cout << "strA: '" << strA << "'" << endl;
    cout << "strB: '" << strB << "'" << endl;
    cout << "strC: '" << strC << "'" << endl;
}

發出錯誤信息

error: no viable conversion from 'string' (aka 'basic_string<char, char_traits<char>, allocator<char> >') to
  'const char'
const char data = _data;

無法為std::stringstream創建新方法。 (至少,我不推薦這個。)

相反,我建議讓它成為一個功能。 用法類似。

#include <bitset>
#include <iostream>
#include <sstream>
#include <string>

using namespace std;

string pop(istream &in, size_t n)
{
  string ret;
  while (n--) {
    unsigned char byte = (unsigned char)in.get();
    ret += bitset<8>(byte).to_string();
  }    
  return ret;
}

int main()
{
  string data(
    "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa"
    "\xbb\xcc\xdd\xee\xff\xde\xad\xbe\xef\x00", 20);
  istringstream in; in.str(data);
  string strA = pop(in, 4);
  string strB = pop(in, 8);
  string strC = pop(in, 8);
  cout << "strA: '" << strA << "'" << endl;
  cout << "strB: '" << strB << "'" << endl;
  cout << "strC: '" << strC << "'" << endl;
  return 0;
}

輸出:

strA: '00010001001000100011001101000100'
strB: '0101010101100110011101111000100010011001101010101011101111001100'
strC: '1101110111101110111111111101111010101101101111101110111100000000'

注意:

  1. 使用std::istream使其適用於從std::istream派生的任何流。

  2. pop()沒有錯誤處理。 因此,如果之后傳遞的流good() ,則pop()的返回結果可能是錯誤的。

順便說一句。 我同意std::stream可能被“過度設計”的評論。 因此,這里的“輕量級”版本:

#include <bitset>
#include <iostream>
#include <string>

using namespace std;

string pop(const char *&iter, size_t n)
{
  string ret;
  while (n--) {
    ret += bitset<8>((unsigned char)*iter++).to_string();
  } 
  return ret;
}

int main()
{
  const char data[] =
    "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa"
    "\xbb\xcc\xdd\xee\xff\xde\xad\xbe\xef\x00";
  const char *iter = data;
  string strA = pop(iter, 4);
  string strB = pop(iter, 8);
  string strC = pop(iter, 8);
  cout << "strA: '" << strA << "'" << endl;
  cout << "strB: '" << strB << "'" << endl;
  cout << "strC: '" << strC << "'" << endl;
  return 0;
}

輸出與上面相同。

注意:

  1. char[]char*的使用對於char[]訪問更加敏感。 因此,必須謹慎使用。

  2. 我不太確定(unsigned char)演員是否必要。 因為我經常看到有關charint和sign擴展的“有趣”效果,我想它不會受到傷害。 (我感覺好多了。)

我可以使用string::substr您提供一個非常簡單的替代方案

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string _data="00010001001000100011001101000100\
0101010101100110011101111000100010011001101010101011101111001100\
1101110111101110111111111101111010101101101111101110111100000000";

  int lenA = (4*8);  //First 4 Bytes
  int lenB = (8*8);  //Second 8 Bytes
  int lenC = (16*8); //Last 16 Bytes

  string strA = _data.substr(0,    lenA - 1);
  string strB = _data.substr(lenA, lenB - 1);
  string strC = _data.substr(lenB, lenC - 1);

  std::cout << "strA: " << strA <<  endl;
  std::cout << "strB: " << strB <<  endl;
  std::cout << "strC: " << strC <<  endl;


  return 0;
}

這很簡單但是可以完成你的工作!
在這里演示

輸出: -

strA: 0001000100100010001100110100010
strB: 010101010110011001110111100010001001100110101010101110111100110
strC: 100110011010101010111011110011001101110111101110111111111101111010101101101111101110111100000000

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM