Попытка сдвинуть каждый бит в строке - PullRequest
0 голосов
/ 21 сентября 2018

Попытка программы кодирования, которая сместит код ascii в каждом символе в строке и распечатает новый символ, чтобы позже я мог сместиться влево и декодировать сообщение.

пример

"#" = 35 или 100011

100011 сдвинут влево один раз = 1000110 или 70

Затем я хочу напечатать "F".

Это то, что у меня есть для кодадо сих пор.Я не понимаю выход.Не уверен, что это потому, что нет кода для символа ascii после 127.

#include <iostream>
#include <string>

using namespace std;

int main ()
{
    int i;

    string str ("Hello World");
    string encode, decode;


    for ( i=0; i<str.length(); ++i)
    {
        cout << str[i];
    }

    cout << endl << endl;

    for ( i=0; i<str.length(); ++i)
    {
        cout << (int) str[i] << " ";

    }

    cout << endl << endl;

    for ( i=0; i<str.length(); ++i)
    {
        encode[i] = (str[i] << 1) ;

        cout << encode[i]  << " ";
    }

    cout << endl << endl;

    return 0;
}

output:

Hello World

72 101 108 108 111 32 87 111 114 108 100 

\220 \312 \330 \330 \336 @ \256 \336 \344 \330 \310 

Ответы [ 2 ]

0 голосов
/ 21 сентября 2018

Итак, давайте перечислим, что вы пытаетесь сделать:

  1. Получить строку в качестве ввода (т. Е. Массив символов)
  2. Преобразовать каждый символ в целое, а затем применить левоесдвиг, а затем сохранить в другой строке, т.е.закодировать, что опять-таки массив символов

Итак, теперь о проблеме:

  1. Вы преобразовываете биты после преобразования в int, что нормально, но после сдвига битов вы пытаетесьсохранить его в массив символов, где каждый символ может быть макс-1 байт и который по-прежнему хранит только символы от -128 до 127 после преобразования в целое число.

Итак, поэтому он никогда не сможет хранить правильную информацию, когда она превысит предел.

Вы все еще можете хранить ее как целое число, например:

encode[i] = ((int) str[i]) << 1 ;

Но проблема будет в том, что когда он превысит свой лимит, он округлится до -128, что в результате приведет к отрицательному списку чисел.

0 голосов
/ 21 сентября 2018

К сожалению, OP не описал ОС и терминал, в котором он пытался, но я думаю, что знаю, что случилось, и осмелюсь написать ответ.

Я описываю это для первой буквы H.(Это случается и со всеми остальными.)

for ( i=0; i<str.length(); ++i)
{
    cout << str[i];
}

Это просто: std::ostream& operator <<(std::ostream&, char) используется и просто печатает H.

for ( i=0; i<str.length(); ++i)
{
    cout << (int) str[i] << " ";

}

Символы (тип char) преобразуются в int.(Преобразование выполняется первым, поскольку его приоритет выше, чем у operator<<().) Следовательно, используется std::ostream& operator <<(std::ostream&, int).Поскольку манипуляторы ввода-вывода не активны, он просто печатает 72 - десятичное значение кода ASCII H.(В C ++ 'H' (char константа) и 72 (int константа) являются просто двумя видами для выражения значения 72.)

for ( i=0; i<str.length(); ++i)
{
    encode[i] = (str[i] << 1) ;

    cout << encode[i]  << " ";
}

Вот что происходит в третьем цикле:

  • str[i] обеспечивает char.
  • operator<<() повышает char до int, поскольку 1 является константой int.
  • operator<<() (в своем первоначальном значении «сдвиг влево в битах») эффективно умножает значение str[i] на 2, т.е. H (== 72) становится 144.
  • Результатом являетсяпреобразуется (зажимается) в char при присвоении encode[i].
  • Значение encode[i] печатается с использованием std::ostream& operator <<(std::ostream&, char) (как в первом цикле).

Сейчасвсе становится туманным, так как я не знаю, где отображается вывод (и как).(Следовательно, мои первоначальные жалобы по поводу отсутствия ОС и тому подобного.)

Тем не менее, я видел похожие результаты при работе в xterm без поддержки UTF-8.

144 может быть непечатным символомв консоли вывода.(Стандарт ASCII описывает только символы со значениями 0 ... 127 и первые 32, а также последние являются управляющими символами.) В этом случае код символа просто печатается в виде восьмеричной последовательности (такой же, как принятыйв строковых литералах C / C ++).

Калькулятор Windows: Декабрь 144 Окт Вывод 220.

Yepp,Это соответствует \220, описанному в OP.


Подумав дважды, я вспомнил, что в UTF-8 никогда не бывает одиночных байтов со значением> = 128.Кодовые точки выше 127 всегда кодируются как минимум с двумя значениями> 128. Следовательно, этот вывод может / должен происходить в терминале с поддержкой UTF-8, а также просто не формирует действительные последовательности UTF-8.


Из любопытства я скомпилировал и протестировал программу OP на coliru и получил:

Hello World

72 101 108 108 111 32 87 111 114 108 100 

� � � � � @ � � � � � 

Live Demo на coliru

* - это, вероятно, заполнители для символов, представляющих недопустимые последовательности UTF-8.Чтобы проверить это, я сделал пример счетчика:

#include <iostream>

int main()
{
  std::cout << "\xc3\x9c\n";
  return 0;
}

, где "\xc3\x9c" предоставляет кодированную последовательность UTF-8 для Ü.

Выход:

Ü

Демонстрация в реальном времени на coliru

...