我有点想要解码我的保存文件。我想出了这个。但是从保存文件中移回字符似乎无法正常工作。只有数字似乎正确恢复,但所有其他字符似乎都变成了奇怪的符号。正如您所看到的,我将savecontent<<<<<<<在左边1,并且在加载时我对输入线进行位移>> 1到右边。但它不像我预期的那样有效。位移不能在字符串上正常工作吗?
void erGuiManager::SaveToFile(string filename) {
ofstream ifs;
ifs.open(filename, ios::binary);
if (ifs.is_open())
{
string savecontent = "";
for (int i = 0; i < guiItems.size(); i++) {
if (dynamic_cast<erGuiBasicNode*>(guiItems[i])) {
savecontent.append( dynamic_cast<erGuiBasicNode*>(guiItems[i])->save(true));
}
}
for (int i = 0; i < savecontent.length(); i++) {
savecontent[i] = savecontent[i] << 1;
}
ifs.write(savecontent.c_str(), strlen(savecontent.c_str()));
ifs.close();
}
else {
cout << "Error: Unable to open file " << filename;
}
}
void erGuiManager::LoadFromFile(string filename) {
string line;
string out;
ifstream myfile(filename);
if (myfile.is_open())
{
while (getline(myfile, line))
{
for (int i = 0; i < line.length(); i++) {
line[i] = line[i] >> 1;
}
out.append(PasteNodeFromString(line,true));
}
ConnectBezierLines(out);
myfile.close();
}
}
答案 0 :(得分:1)
积分促销存在一个微妙的问题(因为operator<<
没有char
,因此它会被提升为int
)并签名延期。
考虑:
int main() {
char a = 127;
printf("%hhd\n", a);
char b = a << 1;
printf("%hhd\n", b);
char c = b >> 1;
printf("%hhd\n", c);
}
及其输出:
127
-2
-1
如您所见,原始值无法恢复。
修复方法是在unsigned
空间内操作,以免发生符号扩展:
int main() {
char a = 127;
printf("%hhd\n", a);
char b = static_cast<unsigned char>(a) << 1;
printf("%hhd\n", b);
char c = static_cast<unsigned char>(b) >> 1;
printf("%hhd\n", c);
}
输出正确:
127
-2
127
在这种特殊情况下,只需要static_cast<unsigned char>(b) >> 1
来解决问题,但是,在执行位移时,应该认识到整体促销和符号扩展。
没有演员:
char(254) >> 1 === int(-2) >> 1 === int(-1) === char(-1)
使用演员:
unsigned char(254) >> 1 === int(254) >> 1 === int(127) === char(127)
答案 1 :(得分:0)
运营商>>
执行arithmetic shift,这意味着所有值&gt; = 64的最高位都有1,这不是您想要的。在ASCII中,数字用48到57之间的值表示,字母从65开始,所以这就是字母不起作用的原因。
一个简单的解决方案是将最高位显式设置为零:
line[i] = (line[i] >> 1) & 0x7f;
这仍然意味着您只能使用字符集的下半部分,即值<127。更好的解决方案是轮班:
line[i] = (line[i] << 1) | (line[i] >> 7)&0x01;
用于编码和
line[i] = (line[i] >> 1)&0x7f |(line[i]<<7);