C++ 计算文本文件中的行数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3482064/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:55:51  来源:igfitidea点击:

counting the number of lines in a text file

c++filegcctext

提问by silent

I'm reading lines off of text file and I'm wondering if this is a good way to go? I had to write the function numberoflinesto decrease the number_of_lines variableby one because within the while loop, for every line it read it adds 2 to the number_of_lines variable.

我正在阅读文本文件中的行,我想知道这是否是一个好方法?我必须编写函数以将 thenumberoflinesnumber_of_lines variable一,因为在 while 循环中,对于它读取的每一行,它会将 2 添加到 number_of_lines 变量中。

#include <iostream>
#include <fstream>
using namespace std;

int number_of_lines = 0;

void numberoflines();
int main(){
    string line;
    ifstream myfile("textexample.txt");

    if(myfile.is_open()){
        while(!myfile.eof()){
            getline(myfile,line);
            cout<< line << endl;
            number_of_lines++;
        }
        myfile.close();
    }
    numberoflines();

}

void numberoflines(){
    number_of_lines--;
    cout<<"number of lines in text file: " << number_of_lines << endl;
}

Is there any other easier better way?

还有其他更简单更好的方法吗?

回答by Jerry Coffin

Your hack of decrementing the count at the end is exactly that -- a hack.

你在最后减少计数的技巧就是——一个技巧。

Far better to write your loop correctly in the first place, so it doesn't count the last line twice.

首先正确编写循环要好得多,因此它不会将最后一行计算两次。

int main() { 
    int number_of_lines = 0;
    std::string line;
    std::ifstream myfile("textexample.txt");

    while (std::getline(myfile, line))
        ++number_of_lines;
    std::cout << "Number of lines in text file: " << number_of_lines;
    return 0;
}

Personally, I think in this case, C-style code is perfectly acceptable:

就个人而言,我认为在这种情况下,C 风格的代码是完全可以接受的:

int main() {
    unsigned int number_of_lines = 0;
    FILE *infile = fopen("textexample.txt", "r");
    int ch;

    while (EOF != (ch=getc(infile)))
        if ('\n' == ch)
            ++number_of_lines;
    printf("%u\n", number_of_lines);
    return 0;
}

Edit: Of course, C++ will also let you do something a bit similar:

编辑:当然,C++ 也会让你做一些类似的事情:

int main() {
    std::ifstream myfile("textexample.txt");

    // new lines will be skipped unless we stop it from happening:    
    myfile.unsetf(std::ios_base::skipws);

    // count the newlines with an algorithm specialized for counting:
    unsigned line_count = std::count(
        std::istream_iterator<char>(myfile),
        std::istream_iterator<char>(), 
        '\n');

    std::cout << "Lines: " << line_count << "\n";
    return 0;
}

回答by strager

I think your question is, "why am I getting one more line than there is in the file?"

我认为您的问题是,“为什么我得到的行比文件中的多一行?”

Imagine a file:

想象一个文件:

line 1
line 2
line 3

The file may be represented in ASCII like this:

该文件可以用 ASCII 表示,如下所示:

line 1\nline 2\nline 3\n

(Where \nis byte 0x10.)

\n字节在哪里0x10。)

Now let's see what happens before and after each getlinecall:

现在让我们看看每次getline调用之前和之后会发生什么:

Before 1: line 1\nline 2\nline 3\n
  Stream: ^
After 1:  line 1\nline 2\nline 3\n
  Stream:         ^

Before 2: line 1\nline 2\nline 3\n
  Stream:         ^
After 2:  line 1\nline 2\nline 3\n
  Stream:                 ^

Before 2: line 1\nline 2\nline 3\n
  Stream:                 ^
After 2:  line 1\nline 2\nline 3\n
  Stream:                         ^

Now, you'd think the stream would mark eofto indicate the end of the file, right? Nope! This is because getlinesets eofif the end-of-file marker is reached "during it's operation". Because getlineterminates when it reaches \n, the end-of-file marker isn't read, and eofisn't flagged. Thus, myfile.eof()returns false, and the loop goes through another iteration:

现在,您会认为流会标记eof以指示文件的结尾,对吗?不!这是因为getline设置eof是否在“操作期间”到达文件结束标记。因为getline在到达 时终止\n,文件结束标记不会被读取,eof也不会被标记。因此,myfile.eof()返回 false,循环进行另一次迭代:

Before 3: line 1\nline 2\nline 3\n
  Stream:                         ^
After 3:  line 1\nline 2\nline 3\n
  Stream:                         ^ EOF

How do you fix this? Instead of checking for eof(), see if .peek()returns EOF:

你如何解决这个问题?与其检查eof(),不如查看是否.peek()返回EOF

while(myfile.peek() != EOF){
    getline ...

You can also check the return value of getline(implicitly casting to bool):

您还可以检查getline(隐式转换为 bool)的返回值:

while(getline(myfile,line)){
    cout<< ...

回答by ashish

In C if you implement count line it will never fail. Yes you can get one extra line if there is stray "ENTER KEY"generally at the end of the file.

在 C 中,如果你实现计数线,它永远不会失败。是的,如果文件末尾通常有杂散的“ENTER KEY”,您可以获得额外的一行。

File might look some thing like this:

文件可能看起来像这样:

"hello 1
"Hello 2

"

Code below

下面的代码

#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "file1.txt"

int main() {

    FILE *fd = NULL;
    int cnt, ch;

    fd = fopen(FILE_NAME,"r");
    if (fd == NULL) {
            perror(FILE_NAME);
            exit(-1);
    }

    while(EOF != (ch = fgetc(fd))) {
    /*
     * int fgetc(FILE *) returns unsigned char cast to int
     * Because it has to return EOF or error also.
     */
            if (ch == '\n')
                    ++cnt;
    }

    printf("cnt line in %s is %d\n", FILE_NAME, cnt);

    fclose(fd);
    return 0;
}

回答by Altinsystems

with for-loop:

使用 for 循环:

std::ifstream myFile;
std::string line;
int lines;

myFile.open(path);

for(lines = 0; std::getline(myFile,line); lines++);

std::cout << lines << std::endl;