Bootstrap

关于c++产生string subscript out of range问题的自己的经历与解决方案

问题背景:

这几天一直在写密码学的实验内容,用的是c++写的,软件是visual studio 2022。本来用的是c写的,但是在用scanf_s()时出现了我无法解决的问题(因为vs不让你使用scanf(),有加个前缀的方法能解决,但是出于安全性考虑,还是用了scanf_s()),而且网上对scanf_s()的用法以及会出现的问题讲解都很少,所以索性放弃了c,改用c++,顺便就当回顾上学期学习的c++。


问题描述:

用到了string和引用&,出现了string subscript out of range的问题(截图就不发了),下面只展示部分关键代码。

#include <iostream>
#include <string>

using namespace std;

//加密算法函数
void EncryptVigenere(string& plain_text, string& key, string& decrypt_text)
{
	//省略很多
	decrypt_text[i] = (plain_text[i] - 'A' + key[j] - 'A') % 26 + 'A';
	//省略很多
}

//main函数
int main()
{
	string plain_text;
	string key;
	string decrypt_text;
	
	//省略很多
	cout << "请输入要加密的字符串:" << endl;
	getline(cin, plain_text);
	cout << "请输入密钥:" << endl;
	getline(cin, key);
	EncryptVigenere(plain_text, key, decrypt_text);
	cout << "得到的密文为:" << decrypt_text << endl;
	//省略很多
	
	return 0;
}

原因分析:

最初看到这个报错的时候,我也很疑惑,那就上网搜吧。网上的说法就是string要初始化,我也照做了,如下,的确成功了:

string plain_text(500,0);
string key(100,0);
string decrypt_text(500,0);

我以为就这样能轻松的解决了,实则不然。在第二个密码学实验中,我使用了同样的方法,然而出现了问题。不展示了,就直接描述。就是在输出后多了很多空行,但实际代码中得到的结果不应该这样啊。

针对第二个实验,我首先进行了对项目的调试,发现在一个循环里似乎有很多次操作,远远大于想要的长度,就比如20,它似乎循环了几百次。那时我似乎有点明白道理了,应该是我赋值的字符串长度导致的,同第一个实验我赋了个500。然后再用调试打印该字符串的长度,果然是500。

至此,我意识到不能简简单单的这样赋值,需要更改写法。


解决方案:

所以之后我就不断在网上以及书上查阅相关的资料,经过不断的尝试后,我找到了比较好的方法:

字符串必须需要初始化,不初始化必定会报错,但初始化的方式可以有多种,以下我只写在本次实验中的赋值方式。

//1.输入赋值
getline(cin,key);

//2.string(长度,值);
string plain_text(500,0);

而第一种方式其实是我一直所忽略的,为什么这么说呢?

string key;		//注意就是这样写,而不是string(100,0);
getline(cin,key);

这种赋值方式会改变key的长度!!!那么可以这样想第一个实验的更优解以及更深次的问题,就是decrypt_text并没有初始化,就访问了下标,所以更好的解决方案就可以如下:

//加密算法函数
void EncryptVigenere(string& plain_text, string& key, string& decrypt_text)
{
	//省略很多
	//修改的地方
	decrypt_text.assign(plain_text_length,0);
	decrypt_text[i] = (plain_text[i] - 'A' + key[j] - 'A') % 26 + 'A';
	//省略很多
}

其他地方都不要变,包括main方法里只需要写类似即可:

string plain_text;
string key;
string decrypt_text;

这种修改方法就是说在输入的时候已经对plain_text和key赋值了,而decrypt_text还没有赋值,所以在加密函数中将decrypt_text初始化明文长度个0(假设明文和密文长度相同)。那么自然而然这种做法牵扯到第二个实验中,就不会产生有多余空行的问题了。

新人第一次发布,如有问题,还请多多指正!

;