使用字符串而不是char数组时程序崩溃

时间:2017-03-19 19:00:29

标签: c++ string

我正在尝试编写一个程序来输入密码等文本(显示“*”而不是用户输入的字符)。

问题是,当我使用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;
}

任何人都可以解释为什么会这样吗?

刚开始使用字符串,对于我来说,了解字符串太多了:)

3 个答案:

答案 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附加到字符串。如有必要,这些将扩大字符串。

在使用动态内存以及您正在访问的内容时,您总是需要注意(例如,在您的第一个示例中,如果您的密码太长,您也会写出界限。)