C++ 如果没有按预期工作? (真的很奇怪的错误)

标签 c++ if-statement

我需要一些帮助,因为我现在真的很绝望。在这里,看看我的这段代码,然后看看输出。是什么导致了这个错误?我该如何解决它?
感谢您提供任何形式的帮助!
代码:

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] 代码时,您实际上是在说“获取字符串中位置 11 处的字符(记住,索引从零开始)”。

所以下面这行代码...

...
else if (username1[3] < 0)
...

字面意思是“字符串中第 4 位的字符是否小于零?”,这显然是无稽之谈(ascii 字符不能为负数)。

您可能想说的是“username1 的长度是否少于三个字符?”,在这种情况下您应该使用 ::strlen方法,像这样:

else if (::strlen(username1) < 3)

然而,正如另一个答案所提到的,如果您使用的是纯 C++,则可能根本不需要使用 username1,您可以调用 std::string::size()在原始的 username 变量上。像这样:

else if (username.size() < 3)

您的代码以意想不到的方式工作的原因是因为您试图在字符串中查找不存在的字符。

想象一下:

username1: [ k | o | k | o | \0 | 4 | f | 6 | 7 | a | 3  | 3 ]
  indexes:   0   1   2   3    4   5   6   7   9   9   10   11

上面是一些原始内存的基本图像,如您所见,在位置零处有字符串 "koko",然后是空终止符,然后是许多不相关的垃圾没有初始化。当您说 username1[10] 时,您将越过输入字符串的末尾并进入与您的字符串变量无关的垃圾内存。所以 if 语句失败了!

但是,由于位置 5-11 的字符未初始化,有时位置 10 的字符可能为零,也可能是其他字符,甚至可能导致程序崩溃!这就是所谓的未定义行为,您应该不惜一切代价避免它!

关于C++ 如果没有按预期工作? (真的很奇怪的错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22128983/

相关文章:

php - 使 if 语句了解哪个 "time-left"格式更大

c++ - std::unique_lock::try_lock_until() 是否忙等待?

c++ - 使用智能指针间接将 std::array 插入堆

java - 使用 if 和 while 接受数组中的元素

if-statement - 谷歌电子表格公式中的多个嵌套 if block

javascript - 当页面不是在 Chrome 中打开时发出警报

c++ - STL容器的只读操作

c++ - 是否有平凡/非平凡成员函数的概念?

c++ - 导出 cmake-gui 选项

将时间戳中的秒转换为纳秒并使用有符号整数表示