2014-12-05 99 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