所以,我试图找出最好/最简单的方法来做到这一点。对于我的算法类,我们应该从一个文件中读取一个字符串(最多包含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表示旋转。 我确定问题在于我正在尝试将字符与数字进行比较并且可能必须转换为ascii?但我只是想问一下,看看是否有更好的方法,并在正确的方向上得到一些指示,因为我对C ++语法很陌生。
一如既往地谢谢。
答案 0 :(得分:2)
使用无格式输入,而不是格式化输入。使用
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;
}
}
答案 1 :(得分:1)
您可以使用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.
模数操作,使用%
运算符,非常适用于需要“环绕”索引的情况。
通过一些算术和数组,可以扩展该过程以处理所有字母和一些符号。
答案 2 :(得分:0)
首先,你必须在比较它们之前将数据字符转换为int,只需将(int)放在char数组的元素之前,你就可以了。
其次,请记住,ASCII表并不以字母开头。有一些有趣的符号直到60-so元素。因此,当你使i等于数据[1]时,你实际上给它的数字高于27,所以循环停止。
答案 3 :(得分:0)
大写字母的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值。
答案 4 :(得分:0)
您可以使用多少标准库?这样的事情可能会更好:
#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;
}
我在此示例中使用了字符串流而不是文件流,因此只需将ss
替换为infile
。另请注意,我没有处理环绕式案例(即,Z + = 1不会给你A;你需要在这里做一些额外的处理),因为我想要把它留给你:))
您的轮换始终为0的原因是i
永远不会== data[1]
。 ASCII字符数字与其整数表示形式不具有相同的基础数字值。例如,如果data[1]
是&#39; 5,那么它的整数值实际上是49. 提示:当您需要知道这些值时处理环绕式箱子。快速google for&#34; ANSI字符集&#34;而且你会看到所有不同的价值观。
您的轮换确定也存在缺陷,因为您只需检查data[1]
。如果您有一个两位数的数字,例如10?