簡體   English   中英

計算文本文件中的行數

[英]counting the number of lines in a text file

我正在閱讀文本文件中的行,我想知道這是否是一個好方法? 我必須編寫函數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;
}

還有其他更容易更好的方法嗎?

你在最后減少計數的黑客就是那個 - 一個黑客。

首先正確編寫循環要好得多,所以它不會計算最后一行兩次。

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

我認為你的問題是,“我為什么要獲得比文件中更多的一行?”

想象一個文件:

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以指示文件的結尾,對吧? 不! 這是因為如果在“操作期間”達到文件結束標記,則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<< ...

在C中,如果你實現計數行,它將永遠不會失敗。 是的,如果文件末尾通常有“輸入鍵”,則可以獲得一行。

文件可能看起來像這樣:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM