[英]Comparing a char
所以,我试图找出最好/最简单的方法来做到这一点。 对于我的算法类,我们应该从一个文件中读取一个字符串(最多包含40个字符)并使用字符串的第一个字符(data [1] ...我们在1处启动数组并希望使用数据[ 0]作为后来的其他东西)作为旋转的旋转次数(最多26个)来旋转后面的字母(基本上是凯撒密码)。
我们尝试做的一个例子是从一个文件中读入:2ABCD和输出CDEF。 我肯定做过尝试,但我不知道如何比较数组char []中的第一个字母,看看它是多少26个数字。 这就是我实现它的方式(不是整个代码,只是我遇到问题的部分):
int rotation = 0;
char data[41];
for(int i = 0; i < 41; i++)
{
data[i] = 0;
}
int j = 0;
while(!infile.eof())
{
infile >> data[j+1];
j++;
}
for(int i = 1; i < 27; i++)
{
if( i == data[1])
{
rotation = i;
cout << rotation;
}
}
我的输出始终为0表示旋转。 我确定问题在于我试图将char与数字进行比较并且可能必须转换为ascii? 但我只是想问一下,看看是否有更好的方法,并在正确的方向上得到一些指示,因为我对C ++语法很新。
谢谢,一如既往。
而不是格式化输入,使用未格式化的输入。 采用
data[j+1] = infile.get();
代替
infile >> data[j+1];
此外, i
与data[1]
的比较需要不同。
for(int i = 1; i < 27; i++)
{
if( i == data[1]-'0')
// ^^^ need this to get the number 2 from the character '2'.
{
rotation = i;
std::cout << "Rotation: " << rotation << std::endl;
}
}
您可以使用modulo
数学来完成此操作,因为字符可以被视为数字。
我们假设只有大写字母(这使概念更容易理解)。
鉴于:
static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const std::string original_text = "MY DOG EATS HOMEWORK";
std::string encrypted_text;
循环:
for (unsigned int i = 0; i < original_text.size(); ++i)
{
让我们将字符串中的字符转换为数字:
char c = original_text[i];
unsigned int cypher_index = c - 'A';
cypher_index
现在包含字母的字母偏移量,例如“A”的索引为0。
接下来,我们通过添加偏移并使用模运算来“循环”来旋转cypher_index
:
cypher_index += (rotation_character - 'A'); // Add in the offset.
cypher_index = cypher_index % sizeof(letters); // Wrap around.
最后,通过查找letters
数组并附加到加密字符串来创建新的移位字母:
encrypted_text += letters[cypher_index];
} // End of for loop.
使用%
运算符的模运算非常适用于需要“环绕”索引的情况。
通过一些算术和数组,可以扩展该过程以处理所有字母和一些符号。
首先,你必须在比较它们之前将数据字符转换为int,只需将(int)放在char数组的元素之前,你就可以了。
其次,请记住ASCII表不以字母开头。 有一些有趣的符号直到60-so元素。 因此,当你使我等于数据[1]时,你实际上给它一个高于27的数字,所以循环停止。
大写字母的ASCII整数值范围为65到90.在C及其后代中,您可以在for循环中使用“A”到“Z”:
更改
for(int i = 1; i < 27; i++)
至
for(int i = 'A'; i <= 'Z'; i++)
你将比较大写值。 该声明
cout << rotation;
将打印从infile
读取的ASCII值。
您可以使用多少标准库? 这样的事情可能会更好:
#include <iostream>
#include <string>
#include <sstream>
int main()
{
int rotation = 0;
std::string data;
std::stringstream ss( "2ABCD" );
ss >> rotation;
ss >> data;
for ( int i = 0; i < data.length(); i++ ) {
data[i] += rotation;
}
// C++11
// for ( auto& c : data ) {
// c += rotation;
// }
std::cout << data;
}
我在这个例子中使用了字符串流而不是文件流,所以只需用你的infile
替换ss
。 另请注意,我没有处理环绕式案例(即,Z + = 1不会给你A;你需要在这里做一些额外的处理),因为我想把它留给你: )
你的轮换总是0的原因是因为i
永远不是== data[1]
。 ASCII字符数字与其整数表示形式不具有相同的基础数字值。 例如,如果data[1]
为'5',则它的整数值实际为49. 提示 :处理环绕情况时,您需要知道这些值。 快速谷歌“ANSI字符集”,你会看到所有不同的价值观。
您对旋转的确定也存在缺陷,因为您只是在检查data[1]
。 如果您有一个两位数的数字,如10,会发生什么?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.