Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> SetFilePointer, так ли я понимаю её работу ? 
:(
    Опции темы
En_t_end
Дата 15.12.2005, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Как я понял, с помошью SetFilePointer можно устанавливать байтовое смещение от определенной точки.
То есть могу ли я делать так:
SetFilePointer(hFile, BytesRealReaded-BytesReaded+1, NULL, FILE_BEGIN);
где BytesRealReaded - есть некая локальная для функция DWORD переменная отвечающая за хранение общего кол-ва прочитанных байт, а BytesReaded - есть локальная для модуля этой функции переменная DWORD отвечающая за хранение байтов прочитанных в последний раз.
Почему-то она неправильно позиционирует указатель, просто дико перемещая его smile
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 15.12.2005, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



должно работать...
может у тебя BytesRealReaded-BytesReaded в отрицательные числа уходит?
что происходит если туда готовые числа подставлять?


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 15.12.2005, 16:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



_hunter
Вот смотри:
Код

BOOL SearchText(LPCTSTR lpszFileName,   LPCTSTR Text, 
                LPDWORD ByteBegConcMas, LPDWORD CountMas)
{
    HANDLE hFile = CreateFile(lpszFileName, GENERIC_READ, 
        FILE_SHARE_READ, NULL, OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        lstrcpy(LastErr, "Can't open file!");
        return FALSE;
    }
    DWORD FileSize = GetFileSize(hFile, NULL);
    char *buffer = new char[lstrlen(Text)+1];
    DWORD BytesReaded = 0;
    DWORD BytesRealReaded = 0;
    while(BytesRealReaded+lstrlen(Text) <= FileSize)
    {
        lstrcpy(buffer, "");
    ReadFile(hFile, buffer, 1, &BytesReaded, NULL);
    BytesRealReaded += BytesReaded;
    if(buffer[0] == Text[0])
    {
        lstrcpy(buffer, "");
        SetFilePointer(hFile, BytesRealReaded-BytesReaded, NULL, FILE_BEGIN);
        BytesReaded = 0;
        ReadFile(hFile, buffer, lstrlen(Text), &BytesReaded, NULL);
        buffer[BytesReaded] = '\0';
        if(CompareStr(buffer, Text))
        {
            ByteBegConcMas[(*CountMas)++] = BytesRealReaded;
            BytesRealReaded += BytesReaded;
        }
        else SetFilePointer(hFile, BytesRealReaded-BytesReaded+1, NULL, FILE_BEGIN);
        MessageBox(NULL, buffer, "ST.DLL:", 0);
    }
    }
//    char buf2[20];    
//    MessageBox(NULL, itoa(*CountMas, buf2, 10), "ST.DLL:", 0);
    CloseHandle(hFile);
    delete[] buffer;
    if(*CountMas == 0) return FALSE;
    return TRUE;
}

PM MAIL ICQ Skype GTalk Jabber   Вверх
En_t_end
Дата 15.12.2005, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



За тупость реализации просьба не пинать...
PM MAIL ICQ Skype GTalk Jabber   Вверх
Aleksandor
Дата 15.12.2005, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Практик
**


Профиль
Группа: Участник
Сообщений: 272
Регистрация: 22.11.2005
Где: россия, зеленогра д

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



А ReadFile сам "file pointer" переставляет smile Так что когда читаем с начала то нет смысла его переставлять.
SetFilePointer обычно нужен только если надо прочитать с конца файла
Код

SetFilePointer(hFile,dwFileLength-175,NULL,FILE_BEGIN);
ReadFile(hFile,ReadBuff+dwFileLength-175,175,&cb,NULL);
........
........
SetFilePointer(hFileOpen,0,NULL,FILE_BEGIN); // теперь в начало



--------------------
Call out Gouranga be happy!!!
Gouranga Gouranga Gouranga ....
That which brings the highest happiness!!
PM MAIL   Вверх
_hunter
Дата 15.12.2005, 16:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



кстати да.
т.е. ( если я правильно понял алгоритм ) достаточно будет SetFilePointer(hFile, -BytesReaded, NULL, FILE_CURRENT); сделать

P.S.
сорри что долго -- отойти нужно было...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 15.12.2005, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(_hunter @ 15.12.2005, 20:59)
т.е. ( если я правильно понял алгоритм )

Совершенно верно, первый вариант как раз таким был, но почему-то он не прошел стресс тест - вылетал екзешен.
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 15.12.2005, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



именно на этой строке летит?


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 16.12.2005, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



_hunter
Не сразу, но летит именно на ней.
Методом научного тыка пришел к такому варианту:
Код

BOOL SearchText(LPCTSTR lpszFileName,   LPCTSTR Text, 
                LPDWORD ByteBegConcMas, LPDWORD CountMas)
{
    HANDLE hFile = CreateFile(lpszFileName, GENERIC_READ, 
        FILE_SHARE_READ, NULL, OPEN_EXISTING, 
        FILE_ATTRIBUTE_NORMAL, NULL);
    if(hFile == INVALID_HANDLE_VALUE)
    {
        lstrcpy(LastErr, "Can't open file!");
        return FALSE;
    }
    DWORD FileSize = GetFileSize(hFile, NULL);
    char first;
    char *buffer = new char[lstrlen(Text)+1];
    DWORD BytesRealReaded = 0;
    while(BytesRealReaded+lstrlen(Text) <= FileSize+1)
    {
            DWORD BytesReaded = 0;
    ReadFile(hFile, &first, 1, &BytesReaded, NULL);
    BytesRealReaded += BytesReaded;
    if(first == Text[0] || *CharLower(&first) == Text[0] || *CharUpper(&first) == Text[0])
    {
        lstrcpy(buffer, "");
        BytesReaded = 0;
        buffer[0] = first;
        ReadFile(hFile, buffer+1, lstrlen(Text), &BytesReaded, NULL);
        buffer[BytesReaded] = '\0';
        if(CompareStr(buffer, Text))
        {
            ByteBegConcMas[(*CountMas)++] = BytesRealReaded;
            BytesRealReaded += BytesReaded;
        }
        else SetFilePointer(hFile, -BytesReaded, NULL, FILE_BEGIN);
    }
    MessageBox(NULL, buffer, "ST.DLL:", 0);
    }
    char buf2[20];    
    MessageBox(NULL, itoa(*CountMas, buf2, 10), "ST.DLL:", 0);
    CloseHandle(hFile);
    delete[] buffer;
    if(*CountMas == 0) return FALSE;
    return TRUE;
}

Теперь вот думаю, почему в таком файле не может найти строку the
файл.txt:
the
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 16.12.2005, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



а почему ты при совпадении строк ( if(CompareStr(buffer, Text)) )
указатель назад смещаеш? по-идее наоборот нужно
+ SetFilePointer(hFile, -BytesReaded+1, NULL, FILE_BEGIN); по-идее смещать нужно ( а то на то же место вернемся )


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 16.12.2005, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



_hunter

Цитата(En_t_end @ 16.12.2005, 19:07)
else SetFilePointer(hFile, -BytesReaded, NULL, FILE_BEGIN);

Там else стоит smile
Моя логика такова: Если нашли подходящую строку, то нафига нам смещать назад указатель ? нам уже пофигу , мы знаем, что позади точно нет неучтенной строки нашего типа(ибо размер мы знаем, он константый, по крайней мере локально)
А если же строка оказалась галиматьей, то надо сместиться назад от прочтенной строки, оказвшись тем самым на месте BytesRealReaded = BytesRealReaded-BytesReaded+1.

Это сообщение отредактировал(а) En_t_end - 16.12.2005, 15:48
PM MAIL ICQ Skype GTalk Jabber   Вверх
JoyEx
Дата 16.12.2005, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дядя
**


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

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



En_t_end
ReadFile/WriteFile изменяют файловый указатель и поэтому лучше перед их вызовом позиционировать его с помощью SetFilePointer.

Чтобы не вылетать на
Код

ByteBegConcMas[(*CountMas)++]

надо передавать в ф-цию размер массива и проверять прежде, чем туда что-то писАть. Зачем читать из файла по 1 байту? Так долго, лучше сразу читать не менее lstrlen(Text) байт и потом не забывать делать Си строку ( + 0 ).

Это сообщение отредактировал(а) JoyEx - 16.12.2005, 16:21


--------------------
Если ты уже никого не боишься, значит ты самый страшный 
PM IM ICQ AOL YIM MSN   Вверх
_hunter
Дата 16.12.2005, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



так при равенстве строк CompareStr ноль отдаст и соответственно произойдет переход на else SetFilePointer(hFile, -BytesReaded, NULL, FILE_BEGIN)...
+ ты ситуацию с -1 не учитываеш...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
En_t_end
Дата 16.12.2005, 17:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



JoyEx
Цитата(JoyEx @ 16.12.2005, 20:21)
надо передавать в ф-цию размер массива и проверять прежде, чем туда что-то писАть.

Дело не в этом, это я учел. Я же показываю лишь тестовую версию, в ней меня не интересует выход за границы, ибо массив передаваемый в моем случае в тестовом коде имеет размер не ниже предполагаемому кол-ву совпадений в файле( я его сам создаю). Я же ведь только тестирую... Естественно я ни в коем случае не возражаю против проверки на выход за пределы выделенной памяти массива smile

Цитата(_hunter @ 16.12.2005, 20:21)
так при равенстве строк CompareStr ноль отдаст и соответственно произойдет переход на else SetFilePointer(hFile, -BytesReaded, NULL, FILE_BEGIN)...
+ ты ситуацию с -1 не учитываеш...

CompareStr - это моя функция smile
Нужна для экспериментов с lstrcmpi stricmp strcmp
Код

BOOL CompareStr(LPCTSTR Str1, LPCTSTR Str2)
{
    if(lstrcmp(Str1, Str2) == 0) return TRUE;
    return FALSE;
}

Сделанна именно так, чтобы не заморачиваться...
Цитата(JoyEx @ 16.12.2005, 20:21)
ReadFile/WriteFile изменяют файловый указатель и поэтому лучше перед их вызовом позиционировать его с помощью SetFilePointer.

Что я и делаю....
Добавлено @ 17:35
JoyEx
Цитата(JoyEx @ 16.12.2005, 20:21)
Так долго, лучше сразу читать не менее lstrlen(Text)

Было бы все так легко smile
файл.txt:
БлtheБtheБлаБлаthe

Таким образом в первый раз прочитается Блt, что не есть гуд smile
PM MAIL ICQ Skype GTalk Jabber   Вверх
_hunter
Дата 16.12.2005, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 8564
Регистрация: 24.6.2003
Где: Europe::Ukraine:: Kiev

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



Цитата(En_t_end @ 16.12.2005, 16:28)
CompareStr - это моя функция smile

ааа... ясно.
просто такая же функция в SysUtils есть. я и подумал что это она...


--------------------
Tempora mutantur, et nos mutamur in illis...
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

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


 




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


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

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