Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;如果没有按预期工作?(真奇怪的虫子)_C++_If Statement - Fatal编程技术网

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']都不是数字