按位移位字符串以解码保存文件C ++

时间:2016-06-17 10:31:04

标签: c++ bit-shift

我有点想要解码我的保存文件。我想出了这个。但是从保存文件中移回字符似乎无法正常工作。只有数字似乎正确恢复,但所有其他字符似乎都变成了奇怪的符号。正如您所看到的,我将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();
    }
}

2 个答案:

答案 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);