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

时间:2011-10-25 05:08:21

标签: c++

我有一个验证用户名字和姓氏的功能。但是,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 << "here\n";
     }
     return name;
}

2 个答案:

答案 0 :(得分:2)

如果cin缓冲区中仍有一些新闻空间字符,可能会发生这种情况。 std :: 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 << "here\n";
     }
     return name;
}

答案 1 :(得分:0)

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

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 << "here\n";

     } while (!stop);

   return name;
}

你在这里有什么:

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

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

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

这不是你想要的。

编辑:,因为' '(空格)为< 'a',您的代码实际上不会导致问题,但我不确定您是否故意这样做。

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

编辑:您可能还想为空输入(所有空格)添加检查,因为这似乎是无效的名称。

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