it-swarm.com.de

zählen der Anzahl von Zeilen in einer Textdatei

Ich lese Zeilen aus einer Textdatei und frage mich, ob dies ein guter Weg ist? Ich musste die Funktion numberoflines schreiben, um den number_of_lines variable um eins zu verringern, da in der while-Schleife für jede gelesene Zeile der Variable number_of_lines 2 hinzugefügt wird.

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

Gibt es einen anderen einfacheren Weg?

21
silent

Ihr Hack, den Zähler am Ende zu dekrementieren, ist genau das - ein Hack.

Es ist viel besser, Ihre Schleife an erster Stelle richtig zu schreiben, damit die letzte Zeile nicht zweimal gezählt wird.

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

Ich persönlich denke, dass in diesem Fall Code im C-Stil durchaus akzeptabel ist:

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: Natürlich lassen Sie sich in C++ auch etwas ähnliches machen:

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;
}
51
Jerry Coffin

Ich denke, Ihre Frage ist: "Warum bekomme ich eine Zeile mehr als in der Datei?"

Stellen Sie sich eine Datei vor:

line 1
line 2
line 3

Die Datei kann in ASCII folgendermaßen dargestellt werden:

line 1\nline 2\nline 3\n

(Wo \n ist Byte 0x10.)

Nun sehen wir, was vor und nach jedem Aufruf von getline passiert:

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:                         ^

Nun denken Sie, der Stream würde eof markieren, um das Ende der Datei anzuzeigen, richtig? Nee! Dies liegt daran, dass getlineeof setzt, wenn die Dateiendemarkierung "während des Betriebs" erreicht wird. Da getline beendet wird, wenn \n erreicht wird, wird die Dateiendemarke nicht gelesen und eof nicht markiert. myfile.eof() gibt also false zurück und die Schleife durchläuft eine weitere Iteration:

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

Wie reparierst du das? Anstatt nach eof() zu suchen, prüfen Sie, ob .peek()EOF zurückgibt:

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

Sie können auch den Rückgabewert von getline überprüfen (implizit in bool konvertieren):

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

Wenn Sie in C eine Zählzeile implementieren, schlägt diese niemals fehl. Ja, Sie können eine zusätzliche Zeile erhalten, wenn "ENTER KEY" im Allgemeinen am Ende der Datei verstreut ist.

Die Datei könnte wie folgt aussehen:

"hello 1
"Hello 2

"

Code unten

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

mit for-Schleife:

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

myFile.open(path);

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

std::cout << lines << std::endl;
0
Altinsystems