C++ 从错误计数的文件中读取数据。什么';什么是读取数据的最佳实践?

C++ 从错误计数的文件中读取数据。什么';什么是读取数据的最佳实践?,c++,file-io,C++,File Io,我有四组文本文件,每个文件包含不同的单词 noun.txt有7个单词 Article.txt有5个单词 verb.txt有6个单词和 Preposition.txt有5个单词 在下面的代码中,在我的第二个for循环中,一个计数数组跟踪我从哪个文件中读取了多少单词。比如说。计数[0]应该是5个世界,但计数[1]有8个单词,但应该是7个。我回去检查了文本文件,没有出错,它有7个单词。这是ifstream的行为问题吗 我还听说eof()不是一个好的做法。在准确读取数据方面,行业最佳实践是什么?换句话说

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

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

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

我还听说eof()不是一个好的做法。在准确读取数据方面,行业最佳实践是什么?换句话说,除此之外,还有更好的东西我可以用吗!infle.eof()

#包括
#包括
#包括
#包括
#include//std::array
使用名称空间std;
const int MAX_WORDS=100;
类Cwords{
公众:
std::数组部分语音;
};
int main()
{
Cwords元素[最大单词];
整数计数[4]={0,0,0};
河流充填;
字符串文件[4]={“Article.txt”,
“Noun.txt”,
“Preposition.txt”,
“verb.txt”};
对于(int i=0;i<4;i++){
infle.open(文件[i]);
如果(!infle.is_open()){
元素[j].词类[i];
计数[i]++;
}
infle.close();
}
出流孔的直径;
outfile.open(“paper.txt”);
如果(!outfile.is_open()){

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

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

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

#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;
    }
#包括
#包括
...
std::字符串行;
int-cnt=0;
而(!infle.eof()){
填充>>行;
boost::算法::修剪(直线);
如果(line.size>0)
字[filenr][cnt++]=行;
}

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

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

#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;
    }
#包括
#包括
...
std::字符串行;
int-cnt=0;
而(!infle.eof()){
填充>>行;
boost::算法::修剪(直线);
如果(line.size>0)
字[filenr][cnt++]=行;
}

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

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

读取文件的主循环应如下所示:

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

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

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

读取文件的主循环应如下所示:

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

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

是的,它拾取了一个换行符。我以为跳过了空格?我如何对此进行调整?问题发生在原因
.eof()
的使用是错误的。它会告诉您在尝试读取某个内容后到达了文件末尾,但那里没有任何内容。它不会预测未来(即,告诉您下一个输入操作是否成功)就像PASCAL那样。是的,它拾取了一个换行符。我以为空格被跳过了?我如何对此进行调整?出现问题的原因是
.eof()
的使用错误。它会告诉您在尝试读取某个内容后到达了文件的结尾,并且出现了错误