尝试移动字符串中的每一位

时间:2018-09-21 01:53:29

标签: c++ bit-shift

尝试使用一个编码程序,该程序可以将字符串中每个字符中的ASCII码移位并打印出新字符,以便以后我可以向左移位并解码一条消息。

示例

“#” = 35或100011

100011左移一次= 1000110或70

然后我要打印“ F”。

到目前为止,这是我要编写的代码。我不理解输出。不知道是不是因为没有超过127的ASCII字符代码。

#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;
}

输出:

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 :(得分:1)

不幸的是,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)。由于没有活动的I / O操纵器,因此仅输出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)的值(如第一个循环一样)。

现在,事情变得模糊了,因为我不知道输出在何处显示(以及如何显示)。 (因此,我最初抱怨缺少操作系统等。)

但是,在没有UTF-8支持的xterm中工作时,我看到了类似的输出。

144在输出控制台中可能是无法打印的字符。 (标准ASCII仅描述值为0 ... 127的字符,而前32和后32是控制字符。)在这种情况下,字符的代码仅打印为八进制序列(与接受的字符相同) C / C ++字符串文字)。

Windows计算器: Dec 144 Oct 输出220

是的。它与OP描述的\220相匹配。


三思后,我记得在UTF-8中从来没有单个字节的值> = 128。高于127的代码点始终使用至少两个> 128的值进行编码。因此,此输出可能/应该在支持UTF-8的终端中发生,并且该输出根本无法形成有效的UTF-8序列。


出于好奇,我在coliru上编译并测试了OP的程序,并得到了:

Hello World

72 101 108 108 111 32 87 111 114 108 100 

� � � � � @ � � � � � 

Live Demo on coliru

可能是代表无效UTF-8序列的字符的占位符。为了检查这一点,我做了一个反例:

#include <iostream>

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

其中"\xc3\x9c"提供了Ü的UTF-8编码序列。

输出:

Ü

Live Demo on coliru

答案 1 :(得分:0)

因此,让我们列出您要执行的操作:

  1. 获取字符串作为输入(即字符数组)
  2. 将每个字符转换为整数,然后应用左移,然后存储在另一个字符串中。再次编码是字符数组

现在,关于这个问题:

  1. 您在转换为int后进行了位移,这很好,但是在位移后,您正在尝试将其存储到字符数组中,其中每个字符可以为最大1个字节,并且在转换为int后仍仅存储从-128到127的字符整数。

所以,这就是为什么它超过限制后将永远无法存储正确信息的原因。

您仍然可以像这样将其存储为整数:

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

但是,问题是一旦超过其限制,它将四舍五入到-128,因此,结果将为负数。