2017-04-27 154 views
0

我有一個程序需要一個文本文件並列出這些文字以及它們被使用了多少次。它的工作原理,但我不知道如何打印出文本文件。在排序的單詞上方以及它們出現的次數之上,我想顯示文件中的文本。我會怎麼做?我嘗試了幾件事情,但它沒有做任何事,或者把代碼的其餘部分搞砸,說有0個獨特的詞。以及最後如何將結果打印出來,使他們有更多...表-ish ...在C++程序中打印.txt文件

/* 
Something like this: 
Word: [equal spaces] Count: 
ask [equal spaces] 5 
anger [equal spaces] 3 
*/ 

謝謝你,你可以給我提供任何幫助。

#include <iterator> 
#include <iostream> 
#include <fstream> 
#include <map> 
#include <string> 
#include <cctype> 

using namespace std; 

string getNextToken(istream &in) { 
    char c; 
    string ans=""; 
    c=in.get(); 
    while(!isalpha(c) && !in.eof())//cleaning non letter charachters 
    { 
     c=in.get(); 
    } 
    while(isalpha(c)) 
    { 
     ans.push_back(tolower(c)); 
     c=in.get(); 
    } 
    return ans; 
} 

string ask(string msg) { 
    string ans; 
    cout << msg; 
    getline(cin, ans); 
    return ans; 
} 


int main() { 


    map<string,int> words; 
    ifstream fin(ask("Enter file name: ").c_str()); //open an input stream 
    if(fin.fail()) { 
     cerr << "An error occurred trying to open a stream to the file!\n"; 
     return 1; 
    } 


    string s; 
    string empty =""; 
    while((s=getNextToken(fin))!=empty) 
      ++words[s]; 

    while(fin.good()) 
     cout << (char)fin.get(); // I am not sure where to put this. Or if it is correct 

    cout << "" << endl; 
    cout << "There are " << words.size() << " unique words in the above text." << endl; 
    cout << "----------------------------------------------------------------" << endl; 
    cout << " " << endl; 

    for(map<string,int>::iterator iter = words.begin(); iter!=words.end(); ++iter) 
     cout<<iter->first<<' '<<iter->second<<endl; 
return 0; 
} 
+0

請修復您的代碼的格式。你的印刷看起來不錯,你確定數據'單詞'包含的是正確的嗎? –

+0

我修好了,所以更容易閱讀。我相信是這樣。它給了我幾個測試文件的正確答案。出於某種原因,我無法獲得打印的實際文件內容。我試圖把'while(fin.good())cout <<(char)fin.get();幾個不同的地方,它搞砸了其餘的代碼。 – rcwade93

+0

我認爲問題在於你試圖讀取輸入文件兩次(一次複製到輸出,一次打破令牌)_但你沒有重置位置!_因此,第二次嘗試將看到一個空文件。請參閱[在此答案中清除'和'seekg'調用](http://stackoverflow.com/a/7681612/2096401)。或者,您可以嘗試交錯打印和令牌化,但除非文件非常大,否則可能不值得。 – TripeHound

回答

1

像這樣的東西應該讓:

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

int main(int argc, char* argv[]) 
{ 
    std::string file; 
    std::cout << "Enter file name: "; 
    std::cin >> file; 

    std::fstream in(file.c_str()); 

    if (in.good()) 
    { 
     std::unordered_map<std::string, int> words; 
     std::string word; 

     //Use this to separate your words it could be '\n' or anything else 
     char cSeparator = ' '; 
     while (in >> word) 
     { 
      //Print the word 
      std::cout << word << cSeparator; 
      ++words[word]; 
     } 

     std::cout << std::endl; 

     //Headers Word and Count separated by 2 tabs 
     std::cout << "Word:\t\tCount:" << std::endl; 

     for (auto& w : words) 
      std::cout << w.first << "\t\t" << w.second << std::endl; 
    } 

    in.close(); 

    return EXIT_SUCCESS; 
} 

然而,這是假設的文本文件只包含的話,如果你有其他類似的東西在那裏,你應該能夠對其進行過濾如你所願。

+0

謝謝你的評論。我很欣賞代碼,因爲它看起來比我的好,而且更短。唯一的問題是它沒有回答我的任何一個問題。如何從文件中以字符串格式打印原始文本?以及如何使輸出成爲帶有Word和Count標題的表格?再次感謝。 – rcwade93

+0

你的意思是按文件順序打印文本? – Gerard097

+0

是的。對不起,如果我措辭不正確。例如,如果文本文件中包含「Peter Piper挑剔等等」,我該如何打印出該句子或故事或文件包含的任何內容,並將其顯示在排序詞表上方? – rcwade93

1

我只想用一個簡單的for循環是這樣的:

for (int x = 0; x < words.size(); x++){ 
    cout >> words[x] << endl 
    } 

然後從那裏修改得到你想要的格式。 但我注意到,在上述代碼的所有路徑中,您沒有返回main的值,這應該會導致編譯時錯誤,但由於某種原因,我沒有編譯它。我會提醒你,你需要有一個main的返回值。除非我誤解你的問題。如果不創建示例文件,我無法運行此程序,因此無法進行額外的測試。但該程序確實進行了編譯。我沒有想到,因爲缺少回報聲明。如果您可以在不需要創建單詞樣本文件的情況下重現您的錯誤,那麼可以將單詞列表插入代碼並儘可能少地重現錯誤,我將能夠更好地爲您提供幫助。事實上,我希望我幫助過你。

+0

與C不同,'main'隱式返回'0',除非你返回其他東西。 – molbdnilo

+0

哦,謝謝!每天學些新東西! –