0

我有四组文本文件,每组都包含不同的单词。

noun.txt 有 7 个单词 Article.txt 有 5 个单词 verb.txt 有 6 个单词 Preposition.txt 有 5 个单词

在下面的代码中,在我的第二个 for 循环中,一个计数数组跟踪我读入了多少单词以及从哪个文件中读取。例如。count[0] 应该是 5 个世界,但是 count[1] 有 8 个单词但应该是 7 个。我回去检查文本文件,我没有弄错,它有 7 个单词。这是 ifstream 行为方式的问题吗?

我也被告知 eof() 不是好的做法。在准确读取数据方面,行业中的最佳实践是什么?换句话说,除了 !infile.eof() 之外,我还能使用更好的东西吗?

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <cctype>
#include <array> // std::array

using namespace std;

const int MAX_WORDS = 100;

class Cwords{
    public:
        std::array<string,4> partsOfSpeech;
};

int main()
{
    Cwords elements[MAX_WORDS];

   int count[4] = {0,0,0,0};

   ifstream infile;

    string file[4] = {"Article.txt",
                      "Noun.txt",
                      "Preposition.txt",
                      "verb.txt"};

    for(int i = 0; i < 4; i++){
        infile.open(file[i]);
        if(!infile.is_open()){
            cout << "ERROR: Unable to open file!\n";
            system("PAUSE");
            exit(1);
        }

        for(int j = 0;!infile.eof();j++){
            infile >> elements[j].partsOfSpeech[i];
            count[i]++;
        }

        infile.close();
    }

    ofstream outfile;
    outfile.open("paper.txt");

    if(!outfile.is_open()){
        cout << "ERROR: Unable to open or create file.\n";
        system("PAUSE");
        exit(1);
    }



    outfile.close();
    system("PAUSE");
    return 0;
}
4

3 回答 3

3

正确读取数据的简单答案是:始终在读取测试读取操作是否成功。本次测试不涉及使用eof()(任何教eof()读前使用的书都值得立即烧掉)。

读取文件的主循环应该是这样的:

for (int j = 0; infile >> elements[j].partsOfSpeach[i]; ++j){
    ++count[i];
}

顺便说一句,尽管该语言称为“C++”而不是“++C”,但除非您确实使用表达式的结果,否则不要使用后自增:在大多数情况下,这无关紧要,但有时它确实很重要,然后后增量可能比前增量慢得多。

于 2013-08-12T21:16:09.323 回答
0

您是否检查过以确保文本文件末尾没有任何多余的空格或换行符?您最后一个额外的“单词”可能是由于eof到达之前的尾随字符。

于 2013-08-12T20:26:07.870 回答
0

文件末尾可能有一个空行,看起来“空”。我的建议是使用如下代码:

#include <boost/algorithm/string.hpp>
#include <string>

...

    std::string line;
    int cnt = 0;
    while(! infile.eof()) {
        infile >> line;
        boost::algorithm::trim(line);
        if(line.size > 0)
            words[filenr][cnt++] = line;
    }

请注意,我强烈建议有一个“外部”对象,它由列表类型索引(如 Article.txt 为 0,Noun.txt 为 1),而“内部”对象是一个向量,它采用字。您的实现是相反的,这是次优的,因为您必须在实现中的 partsOfSpeech 向量中携带空槽。另请注意,在您的示例中,为每个文件的字数设置硬上限“100”是非常危险的 - 它可能导致缓冲区溢出!更好地将 std::vector 用于实际的单词列表,因为向量很容易自动扩展。

于 2013-08-12T20:52:43.387 回答