Russian Qt Forum
Ноябрь 27, 2024, 12:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Количество строк в текстовом файле  (Прочитано 31188 раз)
Andrew Vladoff
Гость
« : Май 14, 2010, 15:53 »

Как узнать количество строк в текстовом файле?
Записан
spectre71
Гость
« Ответ #1 : Май 14, 2010, 15:58 »

Как узнать количество строк в текстовом файле?

Посчитать.
Записан
niXman
Гость
« Ответ #2 : Май 14, 2010, 16:30 »

Код
C++ (Qt)
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <stdexcept>
 
/***************************************************************************/
 
int string_count(const std::string& fname) {
  std::ifstream file(fname);
  if ( !file ) {
     throw std::runtime_error("can`t open file: " + fname);
  }
  return std::distance(
     (std::istream_iterator<std::string>(file)),
     (std::istream_iterator<std::string>())
  );
}
 
int main(int argc, const char** argv) {
 
  std::cout << "strings = " << string_count("main.cpp") << std::endl;
 
  std::cin.get();
  return 0;
}
 
/***************************************************************************/
 
Записан
garryHotDog
Гость
« Ответ #3 : Май 14, 2010, 16:43 »

Можно вот так:
Код
C++ (Qt)
QTextStream stream(&file);
// количество строк.
quint64 linecount=0x00;
QString line;
do
{
    line = stream.readLine();
    // увеличим счетчик строк
    if(!line.isNull()) { linecount++;}
} while (!line.isNull());
 
« Последнее редактирование: Май 14, 2010, 16:46 от garryHotDog » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Май 14, 2010, 18:04 »

Код
C++ (Qt)
  return std::distance(
     (std::istream_iterator<std::string>(file)),
     (std::istream_iterator<std::string>())
  );
 
А что будет если текстовик пришел с др. платформы? Напр сейчас Вы на Linux, а концы строк в файле 10 (Mac) или 13,10 (Вындоуз)?
Записан
niXman
Гость
« Ответ #5 : Май 14, 2010, 18:12 »

в STL, символы завершения строки, зависят от конкретной ОС.
естественно, что ни std::ifstream, ни std::istream_iterator, по умолчанию не выполняют никакой проверки на сей предмет.
при необходимости можно немного допилить.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 14, 2010, 18:21 »

в STL, символы завершения строки, зависят от конкретной ОС.
естественно, что ни std::ifstream, ни std::istream_iterator, по умолчанию не выполняют никакой проверки на сей предмет.
при необходимости можно немного допилить.
Если не затруднит - допилите. Утилитка для создания текстовиков с разными концами строк здесь http://www.prog.org.ru/topic_11267_30.html (последний пост)
Записан
niXman
Гость
« Ответ #7 : Май 14, 2010, 18:33 »

в STL, символы завершения строки, зависят от конкретной ОС.
естественно, что ни std::ifstream, ни std::istream_iterator, по умолчанию не выполняют никакой проверки на сей предмет.
при необходимости можно немного допилить.
Если не затруднит - допилите. Утилитка для создания текстовиков с разными концами строк здесь http://www.prog.org.ru/topic_11267_30.html (последний пост)
то что приатачено тут? : http://www.prog.org.ru/index.php?topic=11267.msg72661#msg72661
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 14, 2010, 18:44 »

то что приатачено тут? : http://www.prog.org.ru/index.php?topic=11267.msg72661#msg72661
да
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #9 : Май 14, 2010, 22:17 »

Код
C++ (Qt)
QFile f("in.txt");
int n = 0;
if (f.open(QIODevice::ReadOnly | QIODevice::Text)
  n = QTextStream(&f).readAll().split('\n').count();
 
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
niXman
Гость
« Ответ #10 : Май 14, 2010, 22:42 »

Код
C++ (Qt)
QFile f("in.txt");
int n = 0;
if (f.open(QIODevice::ReadOnly | QIODevice::Text)
  n = QTextStream(&f).readAll().split('\n').count();
 
а если объем файла 20ГБ или более? тогда что, мейнфрейм покупать? Смеющийся
Записан
garryHotDog
Гость
« Ответ #11 : Май 14, 2010, 22:51 »

split('\n') - более длительная операция, потому что происходит поиск 2ух байт, я думаю обычный пошаговый проход!
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #12 : Май 14, 2010, 23:05 »

Код:
QFile f("in.txt");
int n = -1;
if (f.open(QIODevice::ReadOnly | QIODevice::Text) {
   QByteArray buf;
   do {
       buf = f.readLine();
       n++;
   } while (!buf.isEmpty());
}
мож так?
Записан
ритт
Гость
« Ответ #13 : Май 14, 2010, 23:58 »

Код:
int n = 0;
QFile file("in.txt");
if (file.open(QFile::ReadOnly)) {
    char buf[1024]; // либо QVarLengthArray - для произвольной длины строки
    qint64 lineLength;
    forever {
        lineLength = file.readLine(buf, sizeof(buf));
        if (lineLength > 0)
            ++n;
        else if (lineLength == -1)
            //###
        else
            break;
   }
}
Записан
sendevent
Гость
« Ответ #14 : Май 15, 2010, 03:12 »

чето зацепило  Веселый
дисклаймер: надеюсь, все мы понимаем, что одноразовый тест - не предмет для обсуждения красот и правильностей кода. для тех, хто не понимает - у меня уже готовы куклы вуду, осталось вписать ник  Подмигивающий
а серьезно - если вдруг сотворил дето косяк, пошатнувший основы вселенной - в лс! а то тут начнется...

Код:
#include <iostream>
#include <fstream>
#include <iterator>
#include <algorithm>
#include <stdexcept>

#include <QtGlobal>
#include <QTime>
#include <QFile>
#include <QTextStream>
#include <QStringList>

using namespace std;

/**
** sendevent's variant.
** i think it's possible to get a correct "endl" from the Qt, but idk how =(
*/
#if defined(Q_OS_MAC)
    #define CURRENT_LINES_DELEMITER "\r"
#elif defined(Q_OS_WIN)
    #define CURRENT_LINES_DELEMITER "\r\n"
#elif defined(Q_OS_LINUX)
    #define CURRENT_LINES_DELEMITER "\n"
#else
    message("define your lines ending!")
#endif //-- Q_OS_MAC|Q_OS_WIN

unsigned long sendevent( const char* pFileName )
{
    QFile file( pFileName );
    unsigned long res = 0;
    if( file.open( QIODevice::ReadOnly ) )
    {
        res = file.readAll().count( CURRENT_LINES_DELEMITER );
        file.close();
    }

    return res;
}

/**
** nixMan's variant.
** google it yourselth how to change it for compille with MS VS
** and ignore whitespaces ;-)
*/
unsigned long nixMan( const char* pFileName ) {
   ifstream file( pFileName );
   if ( !file ) {
      throw runtime_error( string( "can`t open file: " ).append( pFileName ) );
   }
   return (unsigned long)distance(
      (istream_iterator< string >(file)),
      (istream_iterator< string >())
   );
}

/**
** garryHotDog's lines counter
*/
unsigned long garryHotDog( const char *pFileName )
{
    QFile file( pFileName );
    unsigned long linecount=0x00;
   
    if( file.open( QIODevice::ReadOnly ) )
    {
        QTextStream stream( &file );
        // количество строк.
       
        QString line;
        do
        {
            line = stream.readLine();
            // увеличим счетчик строк
            if(!line.isNull()) { linecount++;}
        } while (!line.isNull());
       
        file.close();
    }
   
    return linecount;
}

unsigned long kambala( const char *pFileName )
{
    unsigned long n = 0;
    QFile f( pFileName );
    if ( f.open(QIODevice::ReadOnly | QIODevice::Text ) )
    {
        n = QString( f.readAll() ).split(CURRENT_LINES_DELEMITER).count();
        f.close();
    }

    return n;
}

unsigned long konstantin( const char *pFileName )
{
    unsigned long n = 0;
    QFile file( pFileName );
    if ( file.open( QFile::ReadOnly ) )
    {
        char buf[1024]; // либо QVarLengthArray - для произвольной длины строки
        qint64 lineLength;
        forever
        {
            lineLength = file.readLine(buf, sizeof(buf));
            if (lineLength > 0)
            {
                ++n;
            }
            else if (lineLength == -1)
            {
                break;
            }
        }
        file.close();
    }

    return n;
}


/**
** test stuff
*/

typedef unsigned long ( *pointer2function )( const char* );
const char* callTestFunction( pointer2function pFunc, const char *pArg )
{
    QTime time;
    unsigned long iLinesCount, iMsecs;
   
    time.start();
    iLinesCount = pFunc( pArg );
    iMsecs = time.elapsed();
   
    QString strRes( "%1 lines were found at %2 ms" );
    return strRes.arg( iLinesCount ).arg( iMsecs ).toAscii();
}

void createTestFile( const char *pFileName, const char *line,
                     unsigned long ulLinesAmount )
{
    QFile file( pFileName );
    if( file.open( QIODevice::WriteOnly ) )
    {
        QTextStream txtStream( &file );
        for( unsigned long i = 0; i < ulLinesAmount; ++i )
        {
            txtStream << line << i+1 << CURRENT_LINES_DELEMITER;
        }
        file.close();
        cout  << endl << "The " << pFileName << " contains " << ulLinesAmount
                << " lines \""<< line << "\"" << endl;
    }
}

void test( const char* pFile, const char *pLine, unsigned long ulLinesCount, int iTests )
{
    string strFileName( pFile );
    strFileName.append( ".txt" );

    const char *pFileName = strFileName.c_str();
    createTestFile( pFileName, pLine, ulLinesCount );
    pointer2function ptr2Func = NULL;

    for( int i = 0; i < iTests; ++i )
    {
        ptr2Func = &::nixMan;
        cout << callTestFunction( ptr2Func, pFileName ) << " by nixMan" << endl;

        ptr2Func = &::garryHotDog;
        cout << callTestFunction( ptr2Func, pFileName ) << " by harryHotDog" << endl;

        ptr2Func = &::sendevent;
        cout << callTestFunction( ptr2Func, pFileName ) << " by sendevent" << endl;

        ptr2Func = &::kambala;
        cout << callTestFunction( ptr2Func, pFileName ) << " by kambala" << endl;

        ptr2Func = &::konstantin;
        cout << callTestFunction( ptr2Func, pFileName ) << " by konstantin" << endl;
    }
}

int main(int /*argc*/, const char** /*argv*/)
{
    unsigned long ulShortTest = 1024;
    unsigned long ulLongTest = ulShortTest*ulShortTest;

    test( "testShortWithoutSpaces", "line_line", ulShortTest, 1 );
    test( "testShortWithSpaces", "line line",  ulShortTest, 1 );
    test( "testLongtWithoutSpaces", "line_line", ulLongTest, 1 );
    test( "testLongtWithSpaces", "line line", ulLongTest, 1 );
   
    return 0;
}

вкратце:
Цитата: gcc version 4.4.1 /gcc-4_4-branch revision 150839/ (SUSE Linux)
The testShortWithoutSpaces.txt contains 1024 lines "line_line"
1024 lines were found at 1 ms by nixMan
1024 lines were found at 7 ms by harryHotDog
1024 lines were found at 0 ms by sendevent
1025 lines were found at 1 ms by kambala
1024 lines were found at 0 ms by konstantin

The testShortWithSpaces.txt contains 1024 lines "line line"
2048 lines were found at 0 ms by nixMan
1024 lines were found at 1 ms by harryHotDog
1024 lines were found at 0 ms by sendevent
1025 lines were found at 1 ms by kambala
1024 lines were found at 0 ms by konstantin

The testLongtWithoutSpaces.txt contains 1048576 lines "line_line"
1048576 lines were found at 349 ms by nixMan
1048576 lines were found at 777 ms by harryHotDog
1048576 lines were found at 90 ms by sendevent
1048577 lines were found at 884 ms by kambala
1048576 lines were found at 69 ms by konstantin

The testLongtWithSpaces.txt contains 1048576 lines "line line"
2097152 lines were found at 635 ms by nixMan
1048576 lines were found at 776 ms by harryHotDog
1048576 lines were found at 85 ms by sendevent
1048577 lines were found at 864 ms by kambala
1048576 lines were found at 69 ms by konstantin
qt-based варианты (сплит и построчное чтение QTextStream'ом) - самые прожорливые, QString::count( const QString & - не регвыр!) - довольно шустр, но, как и предыдущие, не учитывает размер файла (обходится, но... оно того не стоит, читаем дальше). стл-вариант в текущем виде не канает для студии и в качестве разделетиля всасывает и пробелы (если верить гуглу - лечится, но я не стал заморачиваться).
итог: самый задро почетный нерд этой ночи с пт на сб - Константин!

ps: пока писал тест - обратил внимание: нихто не закрывает файлы. это обусловлено
а) забыл;
б) это пример кода - тут не важно;
в) QFile при уничтожении сам все закроет?
если в) - както я это упустил (а  лезть в ассист - уже лень).
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.263 секунд. Запросов: 23.