我正在阅读带有一行文字的文件。我正在读取文件并根据用户给出的位移更改字符。虽然它适用于某些角色,但对某些角色来说却不然。
我的文件包含以下文字:“这很疯狂”。 当我以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;
}
答案 0 :(得分:3)
变化:
char c = word[i];
要:
unsigned char c = word[i];
答案 1 :(得分:0)
在C和C ++中,你应该始终注意数字溢出,因为语言假设是程序员永远不会犯这样的错误。
char
是一种整数,通常是8位并且有符号,给它一个可接受的范围-128 ... 127。这意味着当您在char
变量中存储值时,不应超过这些边界。
char
也是一种“存储类型”,意味着计算永远不会使用char
进行,例如
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
。
在签名字符变量中存储有符号字符的有效范围之外的值正是您的代码所做的,这就是观察到奇怪行为的原因。 一个简单的解决方案是使用整数来存储中间结果而不是char。
还有一些说明:
EOF
。例如,fgetc
返回int
,isspace
接受int
(它们返回/接受转换为无符号或EOF
的字符的代码。)< / LI>
char
可以签名或不签名,具体取决于编译器/选项;如果是无符号且8位宽,则允许范围为0 ... 255 (char(x + 20) < char(y + 20))
到(x < y)
,因为假设程序员永远不会溢出带符号的数值。