我需要在个人项目的控制台窗口内打印一个Vigenere广场但是我遇到了打印功能的一些问题,因为它偷偷摸摸在其他类中#&# 39;内存并打印出来自它们的字符串。
对于那些不知道什么是Vigenere广场的人来说,这里是picture
这是我的代码:
static void square() {
string cipher[27];
cipher[0] = " | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
for (int i = 0; i < 26; i++) {
string tmp = (char)(i + 'A') + " |";
for (int j = 0; j < 26; j++) {
tmp += " " + (char)(((j + i) % 26) + 'A');
}
cipher[i + 1] = tmp;
}
for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}
我的方法是使用for循环逐个创建每个字符串,该循环增加行的字母ascii值,另一个用于每个颜色移动1的字符。这是奇怪的输出:
我单独运行此代码,但它从我以前用于创建菜单的类中窃取字符串"Invalid Option! Press any key to dismiss."
。我认为它是如何访问保留给该类的部分内存的。
我做错了什么?
答案 0 :(得分:5)
问题在于这两行:
$starttime
首先评估赋值的右侧,然后才是用于构造string tmp = (char)(i + 'A') + " |";
tmp += " " + (char)(j + i + 'A');
的结果。字符串文字通常一起存储在程序的某些静态存储器中。在程序中,文字具有指向该存储器的指针的值。单个字符基本上是一个数字。虽然 + plus运算符用于与std::string
连接,但它对指针和数字的行为却不同。如果你将std::string
添加到char
指针(或任何指针),它只是将指针指向另一个地方 - 在你的情况下指向程序的其他字符串。
要打破它:
char*
假设(char)(i + 'A') + " |"
和i = 0
存储,例如在" |"
上:0xabcd1234
(char)(0 + 65) + (char*)0xabcd1234
(char)65 + (char*)0xabcd1234
- oops,我们没有构造一个连接字符串,我们创建了指向一些随机内存的指针!您可以通过多种方式编写程序。最小的变化是:
(char*)0xabcd1275
这意味着 - 确保+运算符的至少一侧实际上是string tmp = (char)(i + 'A') + string(" |");
tmp += string(" ") + (char)(j + i + 'A');
。
答案 1 :(得分:2)
您的代码中的主要问题是您认为通过将空字符串与char连接将自动变为字符串,这是错误的(这意味着“指向空字符串的某些副本的指针,由数字提前c的值(绝对不是你想要的);&gt;&gt;引自此处:C++ convert from 1 char to string?)。
最终代码可能如下所示:
void square() {
string cipher[27];
cipher[0] = " | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z";
for (int i = 0; i < 26; i++) {
string tmp="";
tmp+=(char)(i + 'A');
tmp+=" |";
for (int j = 0; j < 26; j++) {
tmp += " ";
tmp+=(char)(j + i + 'A');
}
cipher[i + 1] = tmp;
}
for (int i = 0; i < 27; i++) cout << cipher[i] << endl;
}
将字符单独添加到字符串中。
答案 2 :(得分:0)
您正在混淆string
和char
,这可能不是您的意图。我也假设你使用的是std :: string。
不应使用字符串数组,而应使用char数组或字符串。
例如,
string cipher;