подсчет количества строк в текстовом файле

Я читаю строки с текстового файла, и мне интересно, если это хороший способ пойти? Мне пришлось написать функцию numberoflines чтобы уменьшить number_of_lines variable на единицу, потому что внутри цикла while для каждой прочитанной строки она добавляет 2 к переменной number_of_lines.

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

Edit: Конечно, 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(myfile), std::istream_iterator(), '\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: ^ 

Теперь вы думаете, что stream будет отмечать eof чтобы указать конец файла, не так ли? Нету! Это связано с тем, что getline устанавливает eof если 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<< ... в while(getline(myfile,line)){ cout<< ... 

В C, если вы реализуете линию подсчета, она никогда не потерпит неудачу. Да, вы можете получить одну дополнительную строку, если в конце файла находится «КЛЮЧ ВВЕРХ» .

Файл может выглядеть примерно так:

 "hello 1 "Hello 2 " 

Код ниже

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