计算文本文件中的行数

时间:2010-08-14 04:52:27

标签: c++ file gcc text

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

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

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

4 个答案:

答案 0 :(得分:51)

你在最后减少计数的黑客就是那个 - 黑客。

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

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

我个人认为,在这种情况下,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;
}

编辑:当然,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;
}

答案 1 :(得分:5)

我认为你的问题是,“我为什么要获得比文件中更多的一行?”

想象一个文件:

line 1
line 2
line 3

该文件可以用ASCII表示:

line 1\nline 2\nline 3\n

(其中\n为字节0x10。)

现在让我们看看每次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:                         ^

现在,您认为该流会标记eof以指示文件的结尾,对吧?不!这是因为如果到达文件结束标记"during it's operation"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

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

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

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

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

答案 2 :(得分:0)

如果你实现计数行,它将永远不会失败。 是的,如果文件末尾通常存在迷路“ENTER KEY”,则可以获得一行。

文件可能看起来像这样:

"hello 1
"Hello 2

"

以下代码

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

答案 3 :(得分:0)

带有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;