C++ 将cin更改为其他变量后,变量意外更改为0

C++ 将cin更改为其他变量后,变量意外更改为0,c++,C++,我的c++程序有问题:当我验证时,该程序意外地将变量n_alunni设置为0即使我没有写任何其他东西给n\u alunni 代码如下: #include <iostream> #include <string> using namespace std; int main() { int n_alunni=1; char verify[1]; cout<<"Inserisci il numero di alunni: &qu

我的c++程序有问题:当我验证时,该程序意外地将变量
n_alunni
设置为
0
即使我没有写任何其他东西给
n\u alunni

代码如下:

#include <iostream>
#include <string>
using namespace std;

int main()
{
    int n_alunni=1;
    char verify[1];

    cout<<"Inserisci il numero di alunni: ";
    cin>>n_alunni; // I set it to something > 0

    cout<<n_alunni; // n_alunni > 0
    cout<<"Sicuro di voler inserire "<<n_alunni<<" alunni (y,n)?   ";
    cin>>verify;      // <-- After I insert into verify, n_alunni suddenly equals 0
    cout<<n_alunni; // n_alunni == 0
}
#包括
#包括
使用名称空间std;
int main()
{
int n_alunni=1;
字符验证[1];
coutn_alunni;//我将其设置为>0

cout进入
的输入验证
正在写入超出数组边界的内容,覆盖变量中的其他内存。请改用
std::string
或至少将数组大小增加到超出预期的输入长度(并且,为了安全程序,请防止边界冲突!)

更详细地说,与许多上下文中的情况一样,数组参数被“调整”为指向char的指针;这与
istream&operator>>(istream&is,char*s)
匹配。此运算符将标准输入中的“字”复制到指向的内存中。它跳过任何空格(例如,上次按enter键时留下的换行符),然后将字符从stdin复制到指定的内存位置;它在输入中的下一个空格之前停止(例如,按enter键“完成输入”时产生的换行符).在输入字符被写入后,例程用空字符终止输入的1字符“word”,使其成为一个合适的“C字符串”,这是1978年流行的原始方式

如果您输入了一个单字符的单词,则该空字符将被写入到与1字符数组相邻的内存中,在本例中为
n\u alunni
。(您可以通过在
n_alunni
中输入一个大于255的数字来验证这一假设,从而改变更多不受零字节影响的字节。在英特尔体系结构上,单字符输入后的
n_alunni
新值应为
n_alunni&~0xff
,即与输入后的值相同将最低字节归零)


通常情况下,对文本使用
std::string
是处理未知文本的一种更安全的方法。有一种类似于
char*
重载的方法,只会更安全。

verify
的输入超出了数组边界,覆盖了其他内存,其中包括您的变量。请改用
std::string
or至少将数组大小增加到预期的输入长度之外(并且,为了安全程序,防止边界冲突!)

更详细地说,与许多上下文中的情况一样,数组参数被“调整”为指向char的指针;这与
istream&operator>>(istream&is,char*s)
匹配。此运算符将标准输入中的“字”复制到指向的内存中。它跳过任何空格(例如,上次按enter键时留下的换行符),然后将字符从stdin复制到指定的内存位置;它在输入中的下一个空格之前停止(例如,按enter键“完成输入”时产生的换行符).在输入字符被写入后,例程用空字符终止输入的1字符“word”,使其成为一个合适的“C字符串”,这是1978年流行的原始方式

如果您输入了一个单字符的单词,则该空字符将被写入到与1字符数组相邻的内存中,在本例中为
n\u alunni
。(您可以通过在
n_alunni
中输入一个大于255的数字来验证这一假设,从而改变更多不受零字节影响的字节。在英特尔体系结构上,单字符输入后的
n_alunni
新值应为
n_alunni&~0xff
,即与输入后的值相同将最低字节归零)


通常情况下,对文本使用
std::string
是处理未知文本的更安全的方法。有一种类似于
char*
重载的方法,只会更安全。

正如Peter在回答中所说,Tomlynmo在他的评论中,试图将
cin
转换为
char[]
验证
)使C++认为你想编写一个C字符串,它总是有一个“null终止符”来表示字符串的结尾。但是,你的<代码> char [] /Cuth>只长度1,除非你不插入任何东西,否则它会试图写在数组的结尾,导致这个未定义的行为(随机改变其他变量)。

由于您的
verify
不需要是C字符串,您可以将其更改为仅
char verify
,并从中删除任何数组访问业务。
cin
应将其视为正确的字符,而不尝试在其之后写入任何空终止符,以避免意外导致的内存覆盖在彼得的回答中,他把C++中的另一个变量的值改为0。

< p>,在他的评论中,TimLyngMo在试图注释<代码> CIN <代码>到<代码> ChAR[]/Cuff>(<代码>验证< /代码>)使C++认为你想编写一个C字符串,它总是有一个“null终止符”来指示字符串的结尾。
的长度仅为1,因此除非您在其中插入任何内容,否则它将尝试写入数组末尾之外的内容,从而导致这种未定义的行为(随机更改其他变量)


由于您的
verify
不需要是C字符串,您可以将其更改为仅
char verify
,并从中删除任何数组访问业务。
cin
应将其视为正确的字符,而不尝试在其之后写入任何空终止符,以避免意外导致的内存覆盖将另一个变量的值更改为0。

为什么
verify
是一个由单个
char
组成的数组,而不仅仅是一个
char
本身?我不知道如何
std::istream::operator>
ha