2016-06-17 7 views
0

Я вроде как пытаюсь расшифровать мои файлы сохранения. И я придумал это. Но перемещение символов из файла сохранения не работает должным образом. Только цифры, похоже, восстанавливаются правильно, но все остальные символы, похоже, меняются на странные символы. Как вы можете видеть, я смещаю смену savecontent < < 1 влево, а при загрузке я битовый сдвиг входящей строки >> 1 вправо. Но это не работает, как я ожидал. Не работает ли бит-сдвиг на строках?Bit-Shift строка для декодирования файла сохранения C++

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(); 
    } 
} 
+1

Бит сдвига не является обратимым. Вы теряете наивысший бит в своем случае. Это должно работать, если вы используете только базовые символы ascii, которые все <128. Обратимой операцией будет поворот. –

+1

Могу я спросить ... Почему? –

+1

'ifs.write (savecontent.c_str(), strlen (savecontent.c_str()));' - Это не будет работать так, как ожидалось, если 'savecontent' содержит встроенные символы' '\ 0''. «Strlen» остановится при первом нулевом байте. – PaulMcKenzie

ответ

0

Оператор >> делает arithmetic shift, это означает, что все значения> = 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); 
+1

_values> = 64_ вы имели в виду> = 128? –

+1

value> = 128 означает, что старший бит установлен,> = 64 означает, что установлено второе значение. После смещения один раз влево значения, ранее> = 64, имеют самый старший бит. –

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

Спасибо за объяснение! –

+0

Возможно ли, что этот параметр не позволяет использовать все символы? Поскольку числа и буквы работают нормально, но я использую некоторые символы, которые работают некорректно, например, этот символ: § –

+1

@AlexanderS. Он отбрасывает бит наивысшего порядка 'char', поэтому можно восстановить только значения в диапазоне [0, 127]. –