为什么这个while循环在请求name之前执行两次

Why this while loop executes twice before asking for name

本文关键字:执行 两次 name while 循环 请求 为什么      更新时间:2023-10-16

我有一个函数来验证用户的姓和名。然而,while循环执行两次,我不知道为什么....任何帮助

string getName()
{
     string name = "";
     bool stop = false;
     string::iterator it;
     while(!stop)//name validation loop
     {
           cout << "enter name: ";
           getline(cin, name);
           for(it = name.begin(); it < name.end(); it++)
           {
                if(tolower(*it) > 'z' || tolower(*it) < 'a' && tolower(*it) != ' ') 
                { 
                      cout << "Error, only letters! n"; 
                      break;
                }
                if(it == name.end()-1) { stop = true; }
           }
           cout << "heren";
     }
     return name;
}

如果cin缓冲区中仍然有一些新空格字符,则可能发生这种情况。ws从右文本前的流中提取像换行符、空格、制表符这样的空白。试:

string getName()
{
     string name = "";
     bool stop = false;
     string::iterator it;
     while(!stop)//name validation loop
     {
           cout << "enter name: ";
           std::cin >> std::ws;   // <--- drop whitespaces
           getline(cin, name);
           for(it = name.begin(); it < name.end(); it++)
           {
                if(tolower(*it) > 'z' || tolower(*it) < 'a' && tolower(*it) != ' ') 
                { 
                      cout << "Error, only letters! n"; 
                      break;
                }
                if(it == name.end()-1) { stop = true; }
           }
           cout << "heren";
     }
     return name;
}

你的循环有一些问题,这就是我重写它的方式,使它尽可能与你的实现相似:

string getName()
{
   bool stop;
   string name;
   string::iterator it;
   do {
      stop = true;
      cout << "enter name: ";
      getline(cin, name);
      for(it = name.begin(); it < name.end(); it++)
      {
          if( (tolower(*it) > 'z' || tolower(*it) < 'a') && tolower(*it) != ' ' )
          { 
                cout << "Error, only letters! n"; 
                stop = false;
                break;
          }
      }
      cout << "heren";
     } while (!stop);
   return name;
}

用你在这里的一切:

if(tolower(*it) > 'z' || tolower(*it) < 'a' && tolower(*it) != ' ')

由于&&具有更高的优先级,它等于:

if(tolower(*it) > 'z' || ( tolower(*it) < 'a' && tolower(*it) != ' ' ) )

这不是你想要的。

EDIT:由于' '(空格)是< 'a',你的代码实际上不会引起问题,但我不确定你是故意这样做的。

我也不喜欢这个:if(it == name.end()-1) { stop = true; }, do...while循环更合适。

EDIT:您可能还需要添加对空输入(所有空格)的检查,因为这似乎是一个无效的名称。

EDIT(再次): Loki说得对,在调用getName之前,输入流上必须有垃圾。您可以使用Mścisław的解决方案或cin.ignore()