2014-12-05 62 views
0

如果没有输入“密码”,代码会询问用户的名字。如果找到该名称,则将其名称指定为用户。C++不能用键盘输入

代码打击是一个更大的简化版本,但问题是完全一样的。在else语句中,std::cout << "Hello " << FirstName << std::endl;无限重复。如果我删除std::cout << "Hello " << FirstName << std::endl;我无法输入任何内容。就好像我的键盘被拔掉了一样。尝试使用goto,个案,甚至制作一个功能,但问题仍然存在。有任何想法吗?

#include <fstream> 
#include <iostream> 
#include <string> 

int main() 
{ 
std::string User; 
std::string text; 
std::string PassWord; 
std::cin >> PassWord; 
    if(PassWord == "password") 
    { 
     User = "Ryan"; 
    } 
    else if (PassWord != "password") 
    { 
     std::string line; 
     std::string LastName; 
     std::string FirstName; 
     std::string AttemptUser; 
     std::ifstream NameFile; 
     int offset; 

     std::cout << "Name?" << std::endl; 
     NameFile.open("C:\\Filepath\\Names.txt"); 

     if(NameFile.is_open()) 
     { 
      while(!NameFile.eof()) 
      { 
       while(std::cin >> FirstName >> LastName)//<---Needing to press Ctrl-z still a problem! 
       AttemptUser = FirstName + ' ' + LastName; 
       if((offset = line.find(AttemptUser, 0)) != std::string::npos) 
       { 
        NameFile.close(); 
        std::cout << "Hello " << FirstName << std::endl; 
        User = FirstName; 
       } 
      } 
     } 
    } 
    do 
    { 
     std::getline(std::cin, text); 
     if(text.find("the code") != std::string::npos) 
     { 
      std::cout << "Yes " << User << ", this is the code" << std::endl; 
     } 
    } 
while (text != "close"); 
system("pause"); 
return 0; 
} 
+0

你有没有试过设置一个断点并逐步查看会发生什么?你问过你的教授吗? “goto”是邪恶的。此外,你从来没有真正阅读文件,只是打开和关闭它。 – 2014-12-05 21:44:16

+0

有VS 2012 Express所以不能一步一步通过。请详细说明我没有真正阅读文件。可能是我的问题。 – opmxvzasdt 2014-12-05 22:33:12

+0

你可以在4行上引用'NameFile'(顺便说一下,停止在局部变量中大写第一个字符 - 不是很好的做法)。声明,'if(NameFile.is_open())','while(!NameFile.eof())'和NameFile.close()'。在任何时候你都没有从文件中读取数据,所以'.eof()'如果文件存在并且不为空,它将会总是*为假。 – 2014-12-05 23:13:33

回答

1

好了,这里有几个问题,但SO是所有关于学习和固定,所以:

问题零 将一个

using namespace std; 

之前main,并停止把std::前在std::命名空间中的所有内容。不是功能上的差异,但你应该知道这意味着什么。

问题,第一:

  while(std::cin >> FirstName >> LastName)//<---Needing to press Ctrl-z still a problem! 
      AttemptUser = FirstName + ' ' + LastName; 

这将永远重复,除非你强制退出程序(CTRL + C,CTRL + Z等),您可能意味着包括之后的大括号while(...)。不管接下来,这两条线形成一个完整的块,这意味着该行

AttemptUser = FirstName + ' ' + LastName; 

会被一遍又一遍地执行,直到条件

std:cin >> FirstName >> LastName; 

计算为false,这将不会发生。在C++规范中查看cin

你可能有什么意思做的是:

  while(!(std::cin >> FirstName >> LastName))//<---Needing to press Ctrl-z still a problem! 
      AttemptUser = FirstName + ' ' + LastName; 

的区别是微妙的,但很重要。而且,使用字符串作为布尔操作数是愚蠢的。

问题,第二

你永远不会读取文件。它被打开,检查eof,并且最终(理论上它虽然在这个实现中永远不会发生)被关闭,但是你永远不会从文件中读取任何东西。这意味着::eof总是是假的,假设文件存在并且不是空的。

问题,第三

if(PassWord == "password") 
{ 
    ... 
} 
else if (PassWord != "password") 
{ 
    .... 
} 

好吧,这好像是说

if(I am alive) 
{ 
    call me! 
} 
else if (I am not alive) 
{ 
    send flowers or raid the closets; 
} 

跳过()else。在(很多)其他事情中是多余的。

问题,第四

 while(!NameFile.eof()) 
     { 
      while(std::cin >> FirstName >> LastName)//<---Needing to press Ctrl-z still a problem! 
      AttemptUser = FirstName + ' ' + LastName; 
      if((offset = line.find(AttemptUser, 0)) != std::string::npos) 
      { 
       NameFile.close(); 
       std::cout << "Hello " << FirstName << std::endl; 
       User = FirstName; 
      } 
     } 

将在史诗的方式完全失败,如果offset永远等于line.find(AttemptUser,0),因为你关闭该文件,然后检查它的eof在下循环,这将始终发生,除非你已经知道如何通过键盘输入什么也没有。这可能很困难。

其他

如果使用Visual Studio,进入Ctrl+A,然后Ctrl+KD。它应该重新格式化您的代码(取决于您的键绑定),并向您展示有关您的块/缩进结构的有趣事情,这可能会让您感到惊讶。

猜测

我要去无路可退,这不能不说:

 while(!NameFile.eof()) 
     { 
      while(std::cin >> FirstName >> LastName)//<---Needing to press Ctrl-z still a problem! 
      AttemptUser = FirstName + ' ' + LastName; 
      if((offset = line.find(AttemptUser, 0)) != std::string::npos) 
      { 
       NameFile.close(); 
       std::cout << "Hello " << FirstName << std::endl; 
       User = FirstName; 
      } 
     } 

真的应该是这样的:

std::cin >> FirstName >> LastName; 

if (FirstName != "" || LastName != "") 
{ 
    AttemptUser = FirstName + " " + LastName; 
    while(!NameFile.eof()) 
    { 
     getline(NameFile,line); //<< !!!!!!!!!!!!!!! READ THE FILE 
     if (line.find(AttemptUser,0) != string::npos) 
     { 
      /// found 
      cout << "Hello " << FirstName << endl; 
      User = FirstName; /// I hope you don't have multiple users with the same first name. 
      break; // <------- REALLY FREAKING IMPORTANT 
     } 
    } 
    cout << "Who are you?\n"; 
} 

我可以继续下去。修正这个问题,意识到VS2012 Express实际上有一个调试器,并回来提出更多问题。

+0

谢谢!很多东西要去学习。不是作业,只是个人项目。通过学习我可以上网的内容,我在这里解释了许多我无法真正掌握的部分。 **另外**,你在最后一段代码中的评论说:“我希望你没有多个用户名字相同。”这是预料之中的。这就是为什么选中名字和姓氏的原因。如果两者在同一行中都是真的,那么只有该行的第一个名称将被标识为用户。事情是如何建立的呢? – opmxvzasdt 2014-12-06 00:19:16

+0

您正在检查身份验证的第一个和最后一个,但只保留第一个名称(存储在'User'中)以便稍后在您的应用程序中使用。如果你有两个用户 - 史蒂夫J和史蒂夫W - 他们拥有不同的权限,或者如果你想跟踪他们的活动并告诉谁以后做了什么,那么你就无法将他们区分开来。 (老实说,在这一点上,我不会担心。) – 2014-12-08 14:55:01

0

FirstName + LastName = AttemptUser;是不是做你期待什么。 它应该很可能是AttemptUser = FirstName + ' ' + LastName;

它卡在一个infite循环中,因为AttemptUser永远不会被赋予一个值,这导致我说你应该总是初始化你的变量。声明不带值的变量然后像在这里所做的那样引用它们可能会导致非常意外的结果。只要学习一个习惯,即在声明一个变量时始终给出一个初始值,并且可以为您节省很多麻烦。

当你做了FirstName + LastName = AttemptUser;你实际上将AttemptUser的值设为LastName

编辑 不得不做一些调试...变量line从未分配。您没有正确地阅读文件或在任何地方使用其数据。使用std::getline(fstream, string)逐行读取文件。 while(std::cin >> FirstName >> LastName)也应该反转,如“如果用户输入为,则有效时再次读取”。

+0

进行更改并在名称后面,'std :: cout <<“Hello”<< FirstName << std :: endl;'甚至没有输出。似乎我仍然有能够使用键盘的问题。输入名称后,屏幕上没有任何内容。 – opmxvzasdt 2014-12-05 20:52:35