在 C++ 中从 8 位 ASCII 字符创建 7 位 ASCII 文本字符串
Create string of 7-bit ASCII text from 8-bit ASCII chars in C++
我想创建一个最多 46 个八位字节的字符串,用 7 位 ASCII 字符填充。例如,对于字符串 'Hello':
- 我把'H'的后7位(0x48 - 100 1000)放在第一个八位位组的前7位。
- 我取下一个字符 'e' (0x65 - 110 0101),第一位将转到第一个八位位组的最后一位,然后它将填充八位位组 2 的接下来的 6 位。
- 重复 1-2 直到字符串结束,然后剩余的八位字节将用 1 填充。
这是我的尝试,我已经做了很多工作,我尝试过使用 bitset,但它似乎不适合这项任务,因为我不必一直使用 46 个八位字节。如果字符串可以容纳 12(或 24、36)个八位字节(并且只用 1 填充其余部分),那么我不必使用 46.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string a = "Hello";
int N = 0;
if (a.size() <= 11) {
// I'm supposed to implement some logic here to check if it
// will fit 12, 24, 36 or 46 octets but I will do it later.
N = 80;
}
std::vector<bool> temp(N);
int j = 0;
for (int i = 0; i < a.size(); i++) {
std::vector<bool> chartemp(a[i]);
cout << a[i] << "\n";
cout << chartemp[0] << "\n";
cout << chartemp[1] << "\n";
cout << chartemp[2] << "\n";
cout << chartemp[3] << "\n";
cout << chartemp[4] << "\n";
temp[j++] = chartemp[0];
temp[j++] = chartemp[1];
temp[j++] = chartemp[2];
temp[j++] = chartemp[3];
temp[j++] = chartemp[4];
temp[j++] = chartemp[5];
temp[j++] = chartemp[6];
}
for (int k = j; k < N; k++) {
temp[j++] = 1;
}
std::string s = "";
for (int l = 0; l <= temp.size(); l++)
{
if (temp[l]) {
s += '1';
}
else {
s += '0';
}
}
cout << s << "\n";
}
结果是
000000000000000000000000000000000001111111111111111111111111111111111111111111110
您似乎希望语句 std::vector<bool> chartemp(a[i])
将 a
的第 i
个字符作为一系列位复制到向量中。然而向量的构造函数将该值解释为初始大小,a[i]
是 a
中相应字符的 ASCII 值(例如 72
对应 'H'
)。因此,您很有可能创建比预期更大的向量,每个位置都用 false
.
初始化
相反,我建议使用位掩码:
temp[j++] = a[i] & (1 << 6);
temp[j++] = a[i] & (1 << 5);
temp[j++] = a[i] & (1 << 4);
temp[j++] = a[i] & (1 << 3);
temp[j++] = a[i] & (1 << 2);
temp[j++] = a[i] & (1 << 1);
temp[j++] = a[i] & (1 << 0);
您可以使用 temp.push_back(a[i] & (1 << 0))
而不是使用 temp[j++]
,从而也克服了使用正确大小初始化向量的需要。
尝试这样的事情:
#include <string>
#include <vector>
std::string stuffIt(const std::string &str, const int maxOctets)
{
const int maxBits = maxOctets * 8;
const int maxChars = maxBits / 7;
if (str.size() > maxChars)
{
// t0o many chars to stuff into maxOctes!
return "";
}
std::vector<bool> temp(maxBits);
int idx = temp.size()-1;
for (int i = 0; i < str.size(); ++i)
{
char ch = str[i];
for(int j = 0; j < 7; ++j)
temp[idx--] = (ch >> (6-j)) & 1;
}
int numBits = (((7 * str.size()) + 7) & ~7);
for (int i = (temp.size()-numBits-1); i >= 0; --i) {
temp[i] = 1;
}
std::string s;
s.reserve(temp.size());
for(int j = temp.size()-1; j >= 0; --j)
s.push_back(temp[j] ? '1' : '0');
return s;
}
stuffIt("Hello", 12)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 24)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 36)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 46)
returns:
10010001100101110110011011001101111000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
如果您想知道给定字符串需要多少个八位字节(不添加充满 1
的八位字节),您可以使用此公式:
const int numChars = str.size();
const int numBits = (numChars * 7);
const int bitsNeeded = ((numBits + 7) & ~7);
const int octetsNeeded = (bitsNeeded / 8);
如果您想要额外的 1
,只需将 octetsNeeded
舍入到所需的值(例如,下一个 12 的偶数倍数)。
我想创建一个最多 46 个八位字节的字符串,用 7 位 ASCII 字符填充。例如,对于字符串 'Hello':
- 我把'H'的后7位(0x48 - 100 1000)放在第一个八位位组的前7位。
- 我取下一个字符 'e' (0x65 - 110 0101),第一位将转到第一个八位位组的最后一位,然后它将填充八位位组 2 的接下来的 6 位。
- 重复 1-2 直到字符串结束,然后剩余的八位字节将用 1 填充。
这是我的尝试,我已经做了很多工作,我尝试过使用 bitset,但它似乎不适合这项任务,因为我不必一直使用 46 个八位字节。如果字符串可以容纳 12(或 24、36)个八位字节(并且只用 1 填充其余部分),那么我不必使用 46.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
std::string a = "Hello";
int N = 0;
if (a.size() <= 11) {
// I'm supposed to implement some logic here to check if it
// will fit 12, 24, 36 or 46 octets but I will do it later.
N = 80;
}
std::vector<bool> temp(N);
int j = 0;
for (int i = 0; i < a.size(); i++) {
std::vector<bool> chartemp(a[i]);
cout << a[i] << "\n";
cout << chartemp[0] << "\n";
cout << chartemp[1] << "\n";
cout << chartemp[2] << "\n";
cout << chartemp[3] << "\n";
cout << chartemp[4] << "\n";
temp[j++] = chartemp[0];
temp[j++] = chartemp[1];
temp[j++] = chartemp[2];
temp[j++] = chartemp[3];
temp[j++] = chartemp[4];
temp[j++] = chartemp[5];
temp[j++] = chartemp[6];
}
for (int k = j; k < N; k++) {
temp[j++] = 1;
}
std::string s = "";
for (int l = 0; l <= temp.size(); l++)
{
if (temp[l]) {
s += '1';
}
else {
s += '0';
}
}
cout << s << "\n";
}
结果是
000000000000000000000000000000000001111111111111111111111111111111111111111111110
您似乎希望语句 std::vector<bool> chartemp(a[i])
将 a
的第 i
个字符作为一系列位复制到向量中。然而向量的构造函数将该值解释为初始大小,a[i]
是 a
中相应字符的 ASCII 值(例如 72
对应 'H'
)。因此,您很有可能创建比预期更大的向量,每个位置都用 false
.
相反,我建议使用位掩码:
temp[j++] = a[i] & (1 << 6);
temp[j++] = a[i] & (1 << 5);
temp[j++] = a[i] & (1 << 4);
temp[j++] = a[i] & (1 << 3);
temp[j++] = a[i] & (1 << 2);
temp[j++] = a[i] & (1 << 1);
temp[j++] = a[i] & (1 << 0);
您可以使用 temp.push_back(a[i] & (1 << 0))
而不是使用 temp[j++]
,从而也克服了使用正确大小初始化向量的需要。
尝试这样的事情:
#include <string>
#include <vector>
std::string stuffIt(const std::string &str, const int maxOctets)
{
const int maxBits = maxOctets * 8;
const int maxChars = maxBits / 7;
if (str.size() > maxChars)
{
// t0o many chars to stuff into maxOctes!
return "";
}
std::vector<bool> temp(maxBits);
int idx = temp.size()-1;
for (int i = 0; i < str.size(); ++i)
{
char ch = str[i];
for(int j = 0; j < 7; ++j)
temp[idx--] = (ch >> (6-j)) & 1;
}
int numBits = (((7 * str.size()) + 7) & ~7);
for (int i = (temp.size()-numBits-1); i >= 0; --i) {
temp[i] = 1;
}
std::string s;
s.reserve(temp.size());
for(int j = temp.size()-1; j >= 0; --j)
s.push_back(temp[j] ? '1' : '0');
return s;
}
stuffIt("Hello", 12)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 24)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 36)
returns:
100100011001011101100110110011011110000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
stuffIt("Hello", 46)
returns:
10010001100101110110011011001101111000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
如果您想知道给定字符串需要多少个八位字节(不添加充满 1
的八位字节),您可以使用此公式:
const int numChars = str.size();
const int numBits = (numChars * 7);
const int bitsNeeded = ((numBits + 7) & ~7);
const int octetsNeeded = (bitsNeeded / 8);
如果您想要额外的 1
,只需将 octetsNeeded
舍入到所需的值(例如,下一个 12 的偶数倍数)。