【问题标题】:Issue printing .txt file in program C++在程序 C++ 中发出打印 .txt 文件
【发布时间】:2017-04-27 07:23:00
【问题描述】:

我有一个程序,它获取一个文本文件并列出单词及其使用次数。它有效,但我不知道如何打印出文本文件。在排序后的单词及其出现的次数上方,我想显示文件中的文本。我该怎么做?我尝试了几件事,但它要么什么都不做,要么把剩下的代码搞砸了,说有 0 个唯一词。最后,如何打印出结果,使它们更... table -ish...

/*
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;
}

【问题讨论】:

  • 请修正您的代码格式。您的打印看起来不错;您确定words 包含的数据正确吗?
  • 我修复了它,使其更易于阅读。我相信是这样。它给了我一些测试文件的正确答案。由于某种原因,我只是无法打印实际的文件内容。我试着把 'while(fin.good()) cout
  • 我认为问题在于你试图读取输入文件两次(一次复制到输出,一次进入令牌)但你没有重置位置之间! 因此,第二次尝试将看到一个空文件。请参阅clear and seekg calls in this answer。或者,您可以尝试交错打印和标记,但除非文件非常大,否则可能不值得努力。

标签: c++


【解决方案1】:

我会像这样使用一个简单的 for 循环:

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

然后从那里修改以获得您想要的格式。 不过,我确实注意到,您没有在上述代码的所有路径中返回 main 的值,这应该会产生编译时错误,但由于某种原因,在我编译它时没有。我会提醒你,你需要有一个 main 的返回值。除非我误解了你的问题。如果没有创建示例文件,我无法运行该程序,因此如果没有额外的工作就无法对其进行测试。但是程序确实编译了。我没想到,因为缺少退货声明。如果您可以在无需我创建单词示例文件的情况下重现您的错误,将单词列表插入代码并最小程度地重现错误,我将能够为您提供更好的帮助。事实上,我希望我对你有所帮助。

【讨论】:

  • 与 C 中不同,main 隐式返回 0,除非您返回任何其他内容。
【解决方案2】:

应该是这样的:

#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;
}

但是这是假设文本文件只包含单词,如果你有其他类型的东西,你应该能够根据需要过滤它。

【讨论】:

  • 感谢您的评论。我很欣赏这段代码,因为它看起来比我的好,而且更短。唯一的问题是它没有回答我的任何一个问题。如何从文件中以字符串格式打印出原始文本?以及如何将输出变成带有单词和计数标题的表格?再次感谢。
  • 你的意思是按顺序打印文件中的文本吗?
  • 是的。对不起,如果我措辞不正确。例如,如果文本文件包含“Peter Piper pick blah blah”,我如何打印出该句子或故事或文件包含的任何内容并将其显示在排序单词表上方?
  • 我该死的。它就像一个魅力。非常感谢。最后一个问题。如何去掉标点符号?
猜你喜欢
  • 2016-05-13
  • 2021-06-20
  • 2013-03-14
  • 2019-07-18
  • 2012-11-13
  • 2013-08-15
  • 2010-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多