4

我正在阅读带有一行文本的文件。我正在读取文件并根据用户给出的位移更改字符。虽然它适用于某些角色,但它不适用于超出特定点的其他角色。

我的文件包含以下文本:“这太疯狂了”。当我以 20 的位移运行代码时,我得到的是:▒bc▒ c▒ w▒u▒▒

string Security::EncWordUsingRot(int rotNum, string word)
{
  rotNum = rotNum%26;
  string encWord = word;

  for (int i = 0; i < word.size(); i++)
    {
      char c = word[i];
      c = tolower(c);

      if ((c < 'a') || (c > 'z'))
        encWord[i] = c;
      else
        {
          c = (c + rotNum);
          if (c > 'z')
            c = (c - 26);
        }
       encWord[i] = c;
    }
  return encWord;
 }

*编辑** 我更改了注释部分以纠正我的错误。我改unsigned char c = word[i]char c = word[i]. 我还添加了另外两行代码来处理 c 的值低于“a”。我这样做是因为当我想将加密语句恢复为原始形式时,我注意到了一个问题。

string Security::EncWordUsingRot(int rotNum, string word)
{
  rotNum = rotNum%26;
  string encWord = word;

  for (int i = 0; i < word.size(); i++)
    {
      char c = word[i];  //removed unsigned
      c = tolower(c);

      if ((c < 'a') || (c > 'z'))
        encWord[i] = c;
      else
        {
          c = (c + rotNum);
          if (c > 'z')
            c = (c - 26);
          if (c < 'a')  //but I added this if statement if the value of c is less than 'a'
            c = (c + 26);
        }
      encWord[i] = c;
    }
  return encWord;
}
4

2 回答 2

3

改变:

  char c = word[i];

至:

  unsigned char c = word[i];
于 2013-09-22T05:46:26.880 回答
0

在 C 和 C++ 中,您应该始终注意数字溢出,因为语言假设程序员永远不会犯这样的错误。

Achar是一种整数,通常为 8 位且有符号,可接受范围为 -128...127。这意味着当您将值存储在char变量中时,您永远不应超过这些界限。

char也是一种“存储类型”,意味着永远不会使用chars 完成计算,例如

char a = 'z';    // numeric value is 122 in ASCII
int x = a + 20;  // 122 + 20 = 142

x实际上会得到值 142 因为计算没有“溢出”(所有char值首先在表达式中转换为整数)

但是,在变量中存储大于允许范围的值是未定义的行为和代码,例如

char a = 'z';     // numeric value is 122 in ASCII
char x = a + 20;  // 122 + 20 = 142 (too big, won't fit)

是不可接受的:计算很好,但结果不适合x.

在有符号字符变量中存储符号字符的有效范围之外的值正是您的代码所做的,这就是观察到奇怪行为的原因。一个简单的解决方案是使用整数而不是字符来存储中间结果。

还有一些注意事项:

  • 一些关于字符的函数确实在处理整数,因为它们必须能够处理EOF除了所有有效字符之外的特殊值。例如fgetc返回一个intisspace接受一个int(它们返回/接受转换为无符号的字符的代码或EOF)。
  • char可以签名或不签名取决于编译器/选项;如果无符号且为 8 位宽,则允许的范围为 0...255
  • 大多数情况下,将边界外的值存储到变量中时,您只会得到“包装”行为,但这不能保证并且并不总是发生。例如,允许编译器优化(char(x + 20) < char(y + 20))(x < y)因为假设程序员永远不会溢出有符号的数值。
于 2013-09-22T06:29:08.727 回答