C++ C++;如果没有按预期工作?(真奇怪的虫子)
我需要一些帮助,因为我现在真的很绝望。在这里,看一下我的这段代码,然后看一下输出。是什么导致了这个错误?我该如何修复它?C++ C++;如果没有按预期工作?(真奇怪的虫子),c++,if-statement,C++,If Statement,我需要一些帮助,因为我现在真的很绝望。在这里,看一下我的这段代码,然后看一下输出。是什么导致了这个错误?我该如何修复它? 谢谢你的帮助 代码: while (1) { while (1) { cout << "Choose your username: "; cin >> username; std::strcpy (username1, username.c_str()); if (isdigit(username
谢谢你的帮助
代码:
while (1)
{
while (1)
{
cout << "Choose your username: ";
cin >> username;
std::strcpy (username1, username.c_str());
if (isdigit(username1[0]) || isdigit(username1[1]) || isdigit(username1[2]))
{
cout << "The first 3 characters HAVE to contain only letters!\n\a";
}
else if (username1[3] < 0) // I don't actually know why, but this works as intended o.O
{
cout << "Your username HAS to contain atleast 3 letters!\n\a";
}
else if (username1[10] > 0) // Works - dunno why o.0
{
cout << "Your username CAN ONLY contain maximum 10 characters!\n\a";
}
else
break;
}
Choose your username: ko
Your username HAS to contain atleast 3 letters!
Choose your username: k
Your username HAS to contain atleast 3 letters!
Choose your username: kokokokokoo // Now that's > 10
Your username CAN ONLY contain maximum 10 characters! // Now this is okay BUT...
Choose your username: ko
Your username CAN ONLY contain maximum 10 characters! // Wrong error!
Choose your username: kok // This should be accepted!
Your username CAN ONLY contain maximum 10 characters! // Well, it is not... there should not be an error at all!
注意我在输出中添加的注释,这样您就知道哪里出了问题。
谢谢你的回答 username1[10]在输入字符串“kokoo”后,没有任何设置将其设置回零 如果您使用
strncpy
而不是strcpy
,那么(a)您将不会受到缓冲区溢出的影响,并且(b)strncpy
零填充目标,这样您的程序将按您希望的方式工作
但实际上,正如其他评论所说,在复制或使用字符串之前,您应该检查字符串的长度。在将字符串“kokoo”放入字符串后,没有任何设置将
username1[10]
设置回零
如果您使用strncpy
而不是strcpy
,那么(a)您将不会受到缓冲区溢出的影响,并且(b)strncpy
零填充目标,这样您的程序将按您希望的方式工作
但实际上,正如其他评论所说,在复制或使用字符串之前,您应该检查字符串的长度。您不知道它们为什么起作用的部分不起作用。您很可能根本不需要
username1
;您真正应该做的是使用username.length()
检查输入长度:
if(username.length()<3){
//“太短”错误
else if(username.length()>10){
//“太长”错误
您所做的是检查(可能是不确定的垃圾)字符串索引3和10处的字符。
strcpy在将较短的内容复制到字符串中时不会擦除索引10。您不知道它们为什么起作用的部分不起作用。您很可能根本不需要username1
;您真正应该做的是使用username.leng检查输入长度th()
:
if(username.length()<3){
//“太短”错误
else if(username.length()>10){
//“太长”错误
您要做的是检查字符串的索引3和10处的(可能是不确定的垃圾)字符。strcpy
在将较短的内容复制到字符串中时不会删除索引10。方括号中的内容没有执行您认为它正在执行的操作
当您使用username1[10]
代码时,您实际上说的是“给我字符串中第11位的字符(记住,索引从零开始)
所以下面的代码行
...
else if (username1[3] < 0)
...
另一个回答提到,如果你使用纯C++,根本不需要使用<代码> UsReNAME1,你可以只调用原始代码>用户名< /C>变量。
else if (username.size() < 3)
上面是一些原始内存的基本图像,如您所见,在位置0处,您有字符串“koko”
,然后是空终止符,然后是大量未初始化的无关垃圾。当您说username1[10]
,您将通过输入字符串的结尾进入与字符串变量无关的垃圾内存。因此if语句失败
但是,由于位置5-11中的字符未初始化,有时位置10中的字符可能为零,或者可能是其他字符,甚至可能导致程序崩溃!这就是所谓的未定义行为,您应该不惜一切代价避免它!方括号中的内容并不是您认为我在做的事情他在干什么
当您使用username1[10]
代码时,您实际上说的是“给我字符串中第11位的字符(记住,索引从零开始)
所以下面的代码行
...
else if (username1[3] < 0)
...
另一个回答提到,如果你使用纯C++,根本不需要使用<代码> UsReNAME1,你可以只调用原始代码>用户名< /C>变量。
else if (username.size() < 3)
上面是一些原始内存的基本图像,如您所见,在位置0处,您有字符串“koko”
,然后是空终止符,然后是大量未初始化的无关垃圾。当您说username1[10]
,您将通过输入字符串的结尾进入与字符串变量无关的垃圾内存。因此if语句失败
但是,由于位置5-11中的字符未初始化,有时位置10处的字符可能为零,或者可能是其他字符,甚至可能导致程序崩溃!这就是所谓的未定义行为,输入后应不惜一切代价避免此行为!
kokokokokoo
然后退潮
ko
字符数组username1
包含以下内容
[k] [o] ['\0'] [o] [k] [o] [k] [o] [k] [o] [o] ['\0']
0 1 2 3 4 5 6 7 8 9 10 11
所以这个条件在if语句中
if (isdigit(username1[0]) || isdigit(username1[1]) || isdigit(username1[2]))
为false,因为三个字符[k][o]['\0']都不是数字
这种情况
else if (username1[3] < 0)
else if (username1[10] > 0)
是true,因为username1[10]等于大于零的“o”
输入字符串文字后
kok
username1看起来像
[k] [o] [k] ['\0'] [k] [o] [k] [o] [k] [o] [o] ['\0']
0 1 2 3 4 5 6 7 8 9 10 11
事实上,相对于这些条件,并没有发生任何变化。因为username1[10]等于大于零的“o”,所以您会得到消息
Your username CAN ONLY contain maximum 10 characters!
另外,还不清楚为什么要将std::string username类型的对象复制到字符数组username1中
您可以使用username而不是username1进行所有检查,然后如果需要,您可以将username复制到username1中
if ( username.size() < 3)
{
cout << "Your username HAS to contain atleast 3 letters!\n\a";
}
else if ( username.size() > 10)
{
cout << "Your username CAN ONLY contain maximum 10 characters!\n\a";
}
else if ( isdigit( username[0] ) || isdigit( username[1] ) || isdigit( username[2] ) )
{
cout << "The first 3 characters HAVE to contain only letters!\n\a";
}
//...
if(username.size()<3)
{
会议室(10)
{
进入后不能
kokokokokoo
然后退潮
ko
字符数组username1
包含以下内容
[k] [o] ['\0'] [o] [k] [o] [k] [o] [k] [o] [o] ['\0']
0 1 2 3 4 5 6 7 8 9 10 11
所以这个条件在if语句中
if (isdigit(username1[0]) || isdigit(username1[1]) || isdigit(username1[2]))
为false,因为三个字符[k][o]['\0']都不是数字
这