我正在尝试编写一个程序来输入密码等文本(显示“*”而不是用户输入的字符)。
问题是,当我使用char数组来存储密码时,程序运行正常,但是当我为同一目的使用字符串类变量时,我的程序在显示字符串时崩溃。
以下是代码:
// *********THIS CODE WORKS FINE***********
#include <iostream>
#include<string>
#include<conio.h>
int main()
{
using namespace std;
int i=0;
cout<<"Enter a password,press ENTER to finish writing"<<endl;
char passw[20];
passw[i]=getch();
while(passw[i]!=13)
{
i++;
cout<<"*";
passw[i]=getch();
}
passw[i+1]='\0';
cout<<"\nPassword is "<<passw;
return 0;
}
现在,我将char passw[20]
替换为string passw
:
//**********THIS CODE CRASHES!!*********
#include <iostream>
#include<string>
#include<conio.h>
int main()
{
using namespace std;
int i=0;
cout<<"Enter a password,press ENTER to finish writing"<<endl;
string passw;
passw=getch();
while(passw[i]!=13)
{
i++;
cout<<"*";
passw[i]=getch();
}
cout<<"\nPassword is "<<passw;
return 0;
}
任何人都可以解释为什么会这样吗?
刚开始使用字符串,对于我来说,了解字符串太多了:)
答案 0 :(得分:0)
您正在访问std :: string中尚不存在的位置(passw [i]),并且您没有正确地将其存储到字符串中。您应该使用方法passwd.push_back(char)
来存储它。
检查参考:http://en.cppreference.com/w/cpp/string/basic_string/push_back
答案 1 :(得分:0)
在字符串中,您可以使用字符串连接。 您可以保存您的字符并将其添加到字符串变量中。
char ch;
string pass;
ch=getch();
pass=pass+ch;
答案 2 :(得分:0)
与char数组相比,string
的工作方式不同。您可能知道第一个示例中的char passw[20]
创建的数组最多可包含20 char
个空格。然后可以使用operator[]
访问它们而不会出现问题。与基本数组不同,string
是动态数据结构,这意味着随着程序的运行,它会随着时间的推移而增长和缩小。它的内容也可以使用operator[]
访问,但是,这不会附加到字符串,它只能用于更改已经存在的内容。
值得注意的是,在c ++中,并非所有操作都会执行所谓的边界检查。在第二个示例中,您将访问字符串的第i个字符并将字符写入该位置。但是,如果你试图写一个只有5个空格的字符串的第10个字符,会发生什么?当通过operator[]
执行此操作时,程序将写入第10个字符所在的任何位置,即使内存的那部分实际上不是字符串的一部分。任何都可能存在,并将被该操作覆盖。正如您可能想象的那样,这根本不可取,并且可能会在以后导致各种问题。如果你很幸运,你的程序会在写入时立即崩溃。然而,在你的情况下,这不是一件好事;写出越界可能会导致堆损坏(堆是内存的某个部分),这通常会导致某些时候崩溃。
当且仅当您知道您正在访问的索引在字符串大小内时,才可以使用operator[]
来更改string
个字符。否则,您需要使用appropriate member function附加到字符串。如有必要,这些将扩大字符串。
在使用动态内存以及您正在访问的内容时,您总是需要注意(例如,在您的第一个示例中,如果您的密码太长,您也会写出界限。)