2015-09-21 30 views
-1

我試圖從控制檯取用戶輸入而不使用C++標準庫類。這是我的代碼在沒有C++標準庫類的C++中取用戶輸入

while(true){ 
     std::string line = " "; 

     while (getline(std::cin, line)) { 

      std::string arr[100]; 
      int i = 0, len = 0; 
      for (int j=0; j < line.length(); j++) { 
       if(line[j] ==' ' || line[j] == '\n'){ 
        std::string word = line.substr(i, j); 
        arr[len] = word; 
        len++; 
        i = j; 
       } 
      } 
      for (int k = 0; k <len ; ++k) { 
       std::cout<<arr[k]<<std::endl; 
      } 

     } 

     //break; 
    } 

這個想法是識別每個單詞並將其存儲在一個數組中。但是這個程序只能識別第一個單詞。任何想法,我在這裏做錯了什麼。

+2

你覺得stringstream怎麼樣? – Beta

+0

如果你不想使用STL,爲什麼不使用純C代碼? 'scanf'和'printf'。只需要包含頭文件'stdio.h',你應該準備好去... – Nidhoegger

+0

如果你*不能*使用'std :: vector',那麼你需要確保你不會出現在數組之外。但你*應該*使用'std :: vector'。 – crashmstr

回答

1

在閱讀本文時,您的問題似乎在std::string word = line.substr(i, j);。你必須明白substr的論點不是「從i到j」,而是「從i,j個字符」。 Read the documentation. :)

我沒有測試過這個,所以它可能不是完美的,但原理就在那裏。其他

while(true){ 
     std::string line = " "; 

     while (getline(std::cin, line)) { 

      std::string arr[100]; 
      int num_chars = 0, word = 0; 
      for (int i=0; i < line.length(); i++) { 
       /*We increment i, so every non-space character is one we 
       * will include in the word.*/ 
       num_chars++; 
       if(line[i] ==' ' || line[i] == '\n'){ 
        /*We want all characters from i to i+num_chars, that is 
        * we want all characters from j, forward i indices. 
        */ 
        std::string word = line.substr(i, num_chars); 
        arr[word] = word; 
        word++; 
        //We reset i here, in prep for parsing the next word. 
        i = 0; 
       } 
      } 
      for (int k = 0; k <len ; ++k) { 
       std::cout<<arr[k]<<std::endl; 
      } 

     } 

     //break; 
    } 

兩個方面的考慮:

1)當心單字母的變量,因爲它使得更難以供日後閱讀你的代碼。 i是一個循環的標準 terator或 ndex,與j是下一個當你嵌套循環。但是,i不適用於「單詞的長度」。同樣,len不適合存儲單詞的索引。我更改了代碼中的變量以使其更易於閱讀。

2)我會認真考慮重新審視你的循環結構。 while是常見的且非常有用,但它也非常容易出現無限循環。事實上,while(true)是一個無限循環,所以如果你沒有達到break出於任何原因,你會發現一些嚴重的問題。

-

我也同意,如果你想避免「STL」(和,實際上std::stl是經常混淆,但不一樣的東西......讓我們說你要避免std),你會想要避免std::stringstd::cin。正如Nidhoegger所建議的那樣,使用C字符串和scanf/printf。它比std選項更高效,但它也更容易出現C錯誤和「未定義行爲」特性。這需要更多努力,但如果您做得對,則會產生更有效的結果。

雖然我們在這,但我不建議std::stringstream,除非您的其他工具不能很好地完成工作。該班有嚴重的表現和效率問題,這些問題都有詳細記錄。我只建議在使用std::string編寫自己的代碼的情況下使用它,否則這會太費力或者很可能無效。這不是這種情況之一。

+0

雖然我同意你的評估,但它忽略了stringstream的情況。它使用起來非常簡單,應該專注於正確地獲得業務邏輯,而不是獲取數據的基本內容。除非在*中獲取數據的本質是業務邏輯或極其殘酷的低效率像stringstream這樣的通用工具會阻礙在所需參數內執行業務邏輯。對於作業而言,業務邏輯不是代碼,它正在學習作業應該教的教訓。完成它,學習,然後繼續下一項任務。 – user4581301

+0

@ user4581301:一方面,是的,你是對的。 「完成它」通常是一個好方法。另一方面,習慣性地使用像std :: stringstream這樣低效率的解決方案存在固有的危險。互聯網充滿了輕率的使用它的建議,其中包括許多會對性能產生不利影響的情況。人們應該學會如何儘早做到手動操作,比如學習駕駛換檔車。如果你知道如何,你將無法駕駛自動駕駛儀。另外,你可以更好地辨別何時使用'stringstream',以及何時不要。 – CodeMouse92

+0

我們在這個話題上可能存在的唯一不一致意見是教授手冊的可能性。 – user4581301