Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> правильно подсчитать колличество строк в файле, без STL  
V
    Опции темы
TupDub
Дата 18.1.2010, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 21.11.2009

Репутация: нет
Всего: нет



Привет Народ, подобные вопросы не раз обсуждались, но я пошарив не нашёл ответа!
Хотелось бы, чтобы моя программа считали колличество строк и слов в файле.
Вот файлик: 
Код

#include <stdio.h>
#include <cstdio>
#include <string.h>
int main ( int argc, char *argv[] )
{
    if ( argc > 1 ) 
    {
        int     iNumWords=0, iNumLines=0, iNumChars=0, iNumBytes=0, ilongest_str = 0, istr=0, iPrvPos=0, iPosEnd=0, iPosCur=0;
        char cNumWords[10], cNumLines[10], cNumChars[10], cNumBytes[10];
        char cResultString[100], cFilename[255], cString[100];
        const char *cBedStr = "\t\n";
        char *cStr, *cPoint;
        for ( int i = 1; i<argc; i++ )  sprintf ( cFilename, "%s",argv[i] );
        FILE * pFile = fopen ( cFilename, "r" );
        if ( pFile==NULL ) perror ( "Error opening file " );
        else
        {
            fseek ( pFile, 0, SEEK_END );
                iPosEnd = ftell(pFile);
                iNumChars = iPosEnd + 1;
            fseek ( pFile, 0, SEEK_SET );
            while ( !feof ( pFile ) ) 
            {
                char c = fgetc ( pFile );
                if ( (  c == '\n' ) || ( iPosCur == ( iPosEnd-1 ) ) )
                {
                    iNumLines++; 
                    int iPos = ftell ( pFile );
                        fseek ( pFile, iPrvPos, SEEK_SET );
                        cStr = fgets ( cString, iPos+1, pFile );
                        iPrvPos = ftell ( pFile );
                    if ( ( strlen ( cStr ) > 1 ) && ( strcmp ( cStr, cBedStr ) ) )
                        for ( cPoint = strtok ( cStr, " " ); cPoint != NULL; cPoint = strtok ( NULL, " ") ) iNumWords++;
                    if ( ilongest_str > istr ) istr = ilongest_str;
                        ilongest_str=0;
                }
                    ilongest_str++; iPosCur++;
            }
                   iNumBytes = ( int ) sizeof ( char )* ( iNumChars-1 );
            
            printf ( "  %d  %d %d %s\n", iNumLines, iNumWords-1, iNumChars-1, cFilename );
                    fclose ( pFile );
        }
    }
        return ( 0 );
}

И ещё при подсчёте количества строк, она не считает пустую строку за строку, пока я там не напечатаю символ какой нить, не понимаю почему....
пример 
Код

1 First string
2 Second string 2+

3 Thyrde
1
    

в этом файле 6 строчек и моя программа считает что 6.
Код

1 First string
2 Second string 2+

3 Thyrde
1


в этом файле тоже шесть, но в шестой нет знака ТАБа как в прошлом примере и моя программа говорит, что строк 5!
Может кто подскажет, как это исправить ?
Всё без STL только Си.
спасибо.
PM   Вверх
djamshud
Дата 18.1.2010, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Ммапите весь файл в память и считаете количество символов переноса строки, отбрасывая варианты, когда предыдущий символ - тоже перенос строки. Со словами то же, только там пробел - разделитель.

Ваш код не читал, но издалека выглядит ужасно.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
bsa
Дата 18.1.2010, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



как-то очень сложно...
1. читаешь символ из файла с помощью fgetc
2. проверяешь его с помощью isspace()
3. если false: проверяешь с помощью isalpha(), если true, то присваиваешь word=true
4. иначе, то если word==true, увеличиваешь количество слов и word = false, а если еще и символ == '\n' или -1, то увеличиваешь количество строк

Это сообщение отредактировал(а) bsa - 18.1.2010, 16:00
PM   Вверх
djamshud
Дата 18.1.2010, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



>1. читаешь символ из файла с помощью fgetc

Не делайте так никогда, кроме совсем экзотических случаев, в которых вы поймете, что делать нужно только так и никак иначе. Затрахаете винт неистовыми обращениями, а пока программа будет все это пережевывать, успеете попить чайку.

Вместо mmap-а можно читать файл буферами и анализировать их.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
bsa
Дата 18.1.2010, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(djamshud @  18.1.2010,  12:55 Найти цитируемый пост)
Вместо mmap-а можно читать файл буферами и анализировать их. 
смысл всех функций, работающих с FILE, - буферизация. Т.е. это именно то, о чем ты говоришь, только не нужно самому что-либо делать.

PM   Вверх
shuttle
Дата 18.1.2010, 13:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 9.4.2008

Репутация: нет
Всего: нет



зачем проверять каждый символ, считать все строки из файла, параллельно считая их количество
Код

ifstream fin;
char line[100];

fin.open("path.txt");    

int numOfLen=0;
while(fin.getline(line,100))
    numOfLen++;

--------------------
PM MAIL   Вверх
bsa
Дата 18.1.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(shuttle @  18.1.2010,  13:01 Найти цитируемый пост)
зачем проверять каждый символ
затем, чтобы посчитать еще и количество слов.

PM   Вверх
Alca
Дата 18.1.2010, 13:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 2
Всего: 50



shuttle, а если строка больше 100 символов?


--------------------
PM WWW ICQ Skype Jabber   Вверх
bsa
Дата 18.1.2010, 13:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(Alca @  18.1.2010,  13:07 Найти цитируемый пост)
shuttle, а если строка больше 100 символов? 
Вариант shuttle вообще не "катит", так как у ТС русским языком написано про язык Си.

PM   Вверх
djamshud
Дата 18.1.2010, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



bsa, буферизуется возможно, да. Но вариант с нормальным буфером - 1 сек, посимвольное чтение - 42 сек.

ЗЫ. файл - гиг с хвостиком

ЗЗЫ.

Код

#include<stdio.h>
#include<errno.h>
#include<string.h>

//just for get a lot of fun
//#define HOLYSHIT

int main(){

//small file. just for test
//FILE *file=fopen("file.cpp","r");

//large file. just for lulz
    FILE *file=fopen("/mnt/usbhdd/video/Deep.Purple.History.Hits.Highlights.(2.chasti.iz.2).2009.DVDRip_[torrents.ru]/Deep.Purple.History.Hits.Highlights.(1.chast.iz.2).2009.DVDRip-LTarik.avi","r");

    if (file==0)printf("%s\n",strerror(errno));
    int cnt=0;

#ifdef HOLYSHIT

    while (feof(file)==0)
        if (fgetc(file)=='\n')cnt++;

#else

    char buf[1024*1024];
    while (feof(file)==0){
        char *ptr=buf-1;
        buf[fread(buf,sizeof(char),sizeof(buf)-1,file)]='\0';
        while ((ptr=strchr(ptr+1,'\n'))!=0)cnt++;
    }

#endif

    fclose(file);
    printf("Newlines: %d\n",cnt);

    return 0;
}


ЗЗЗЫ. Дефолтная оптимизация на максимуме (-O3).

Это сообщение отредактировал(а) djamshud - 18.1.2010, 15:19


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
bsa
Дата 18.1.2010, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



djamshud, по скорости я спорить не буду (так как знаю, что на вызов fgetc тратится время, а, учитывая объемы, - существенное). Сам стараюсь не пользоваться всем что связано с FILE. Но в данном случае, я считаю, что ТС будет проще написать код по моему совету, а потом объяснить его.

djamshud, ты бы хоть код отформатировал. Какой пример новичкам подаешь?
PM   Вверх
djamshud
Дата 18.1.2010, 15:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



bsa, новичку, я думаю, в любом случае нужно хотя бы знать, как правильнее делать в принципе.

Поправил, сорри.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
TupDub
Дата 18.1.2010, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 46
Регистрация: 21.11.2009

Репутация: нет
Всего: нет



bsa, 
djamshud, Спасибо за ответы... буду пробыаать! о результатах напишу!
может не совсем в этото топик вопрос, но не хочу флудить... 
От чего при запуске это проги в винде возникает ошибка:
An unhandled win32 exception occurred in main.exe. ? ? ?




Это сообщение отредактировал(а) TupDub - 18.1.2010, 18:14
PM   Вверх
djamshud
Дата 18.1.2010, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Пердупержденный
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 23.11.2009

Репутация: 4
Всего: 39



Этой - моей? Неправильно обработано условие невозможности открыть файл на чтение, не обработана возможная ошибка чтения файла. Это как минимум.

Этот пример я писал скорее товарищу bsa, чтобы показать убогость посимвольного чтения, он показывает идею, как в принципе нужно делать, и не претендует на звание "хорошего". "Как нужно" - ИМХО конечно и при условии не использования отображения файла в память - некроссплатформенного системного вызова.


--------------------
'Cuz I never walk away from what I know is right
Alice Cooper - Freedom
PM   Вверх
shuttle
Дата 19.1.2010, 05:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 230
Регистрация: 9.4.2008

Репутация: нет
Всего: нет



Цитата

shuttle, а если строка больше 100 символов? 

по больше буфер сделать.

Цитата

Вариант shuttle вообще не "катит", так как у ТС русским языком написано про язык Си.

Я просто идею подсказал, что бы считывание посрочно было, т.к. до моего поста только по символьно. И написано не использовать STL.
--------------------
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0643 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.