2017-04-27 74 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

哦,谢谢!每天学些新东西! –