![]() |
|
Модераторы: feodorv, GremlinProg, xvr, Fixin |
![]()
|
|
| wallstreet |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Всем дообрый день.
Передо мной стоит задача посчитать символы и слова в тектовом файле, предварительно спроецированным в память. Как пишут учебники, функция MapViewOfFile() проецирует файл на зарезервированное пространство и возвращает указатель на начало области памяти "проекции файла" с которым можно работать как с обычным одномерным массивом. Соответственно сразу рождается идея обычным циклом пробежаться по всем символам и понаходить пробелы + 1. Так мы найдем кол-во слов. А вот кол-во символов посчитать мне, поидее, должна помочь функция GetFileSize(), однако она возвращает DWORD. Соственно вопросы: 1) Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла? 2) Как конвертировать DWORD в int или какой функцией можно из значения переменной DWORD сделать строку? |
|||
|
||||
| feodorv |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Неужели этот так страшно? DWORD - сокращение от "double word" - "двойное слово" (4-х байтовая переменная). А можно и заглянуть в windef.h и увидеть такое:
То есть это, действительно, тип для 4-х байтовой беззнаковой переменной. Для win32 и win64 совпадает с "unsigned int". Поэтому вопрос отпадает сам собой. Внимательный осмотр вызова GetFileSize() показывает, что "она" возвращает не одно значение DWORD, а целых два
Гм.
LPVOID:
То есть фактически LPVIOD есть "void *", указатель на память с проекцией файла. Работать с void * побайтово не очень удобно, но никто нам не мешает сделать так:
И работайте себе (относительно) спокойно с mem как массивом байт... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||
|
|||||||||||
| Dem_max |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1780 Регистрация: 12.4.2007 Репутация: 16 Всего: 39 |
или так
-------------------- Американские программисты долго не могли понять, почему русские при зависании Windоws всё время повторяют "Твой зайка написал" ("Yоur bunnу wrоte") |
|||
|
||||
| wallstreet |
|
||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то? Вобщем опишу более детально на чем застопорился. Создал функцию которая считает слова в тексте, а кол-фо символов, включая пробелы буду определять функцией GetFileSize(). Проецирую файл:
вот так формирую строку и вывожу данные в WM_PAINT:
функция считающая слова и символы:
Мне кажется что я все делаю неправильно. Укажите с чего начинать исправлять ситуацию? Кстати непонятно что значит плохой указатель (Bad Ptr): ![]() ссылка на проект Проект Это сообщение отредактировал(а) wallstreet - 8.5.2012, 17:48 |
||||||||
|
|||||||||
| feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Ну, если печатать так: величины, которые объявлены как int, то, да, 12 может превратиться во что угодно. Намёк: 4 байта = 32 битам, никак не 64. Ну и? А где fSize / sizeof(TCHAR)? И почему fSize, а не WordCount(p, SimbolsCount(fSize))? И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот? По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно: Здесь точно ' ', даже для UNICODE версии программы? А если два пробела подряд? А если табуляция или, не дай Бог, перевод строки? Это значит указатель, который указывает на регион памяти, не переданный данному процессу. Процессу принадлежат его 4 гига (или больше для 64-х битных ОС), но не вся эта память является действительной (зарезервированной процессом). Иначе говоря, p указывает непонятно куда. Почему 0xcccccccc? Потому что:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
| Albor |
|
|||
|
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 589 Регистрация: 28.2.2009 Репутация: нет Всего: 9 |
Ишь, как просто слова считать... Это сообщение отредактировал(а) Albor - 11.5.2012, 11:17 |
|||
|
||||
| wallstreet |
|
||||||||||||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
я понял, исправил на:
функция
может я в чем-то заблуждаюсь, но возвращает правильное кол-во символов в файле. ![]()
Честно признаться, я знаю в чем отличие между двумя этими кодировками но как определить кодировку в которой находится файл не имею понятия. Может по символам которые в 256 битную таблицу ASCII не влазят пробежаться циклом, или как? Вообще я думал что если я читаю текстовый файл и при этом использую расширенную кодировку в разных функциях работы с файлом, то все будет получаться, т.к. UNICODE содержит все символы и буквы кодировки ASCII. Хммм... в смысле число байт? т.е. в виде двоичной системы счисления? В таком случаем с помощью какой функции можно конвертировать данные в символы? Или каким методом?
в объявлении:
помогло.
Я понял, переделал на вот так:
но по всей видимости у меня действительно кракозябры вместо символов текста с которыми я сравниваю буквы из моего массива, соответственно ни одного совпадения по буквам не происходит поэтому счетчик нулевой. Данным примером я хочу показать принцип, с помощью которого, по моему мнению нужно решать задачу. Если я ошибаюсь прошу поправить. всех участвующих благодарю за бесценный вклад в мои знания. чуть не забыл ->ссылка на проект Это сообщение отредактировал(а) wallstreet - 14.5.2012, 18:08 |
||||||||||||||
|
|||||||||||||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
боже мой, ... ... Добавлено через 12 минут и 45 секунд wallstreet, это был ацкий кот! Я бы слова подсчитывал по следующему простому алгоритму. Если текущий символ - есь буква, а предыдущий был не буква, это есть начало слова. Конец ведь нам не нужен То что конец будет, (и причем всему, уже скоро) это аксиома. Даже если текст оборвется на середине слова, мы это слово обязаны засчитать. Ну и алгоритм упрощается,
Задолбался писать комментарии... |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
Вообще хорошо бы точное определение, что считать словом.
Если например вы хотите набор цифр и букв идущих подряд считать одним словом, то _istalpha() нужно заменить на _istalnum() Это сообщение отредактировал(а) volatile - 15.5.2012, 00:59 |
|||
|
||||
| wallstreet |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
Спасибо, то что надо!
Проект компилируется и отрисовывает правильный результат, но после этого выскакивают ошибки с которыми не могу справиться. ![]() Подскажите в связи с чем эти ошибки и как я могу их устранить? ссылка на проект Это сообщение отредактировал(а) wallstreet - 16.5.2012, 12:00 |
|||
|
||||
| volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 13 Всего: 85 |
||||
|
||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
судя по содержимому окна output, край которого все же видно, это повреждение кучи,
которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
| wallstreet |
|
||||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 153 Регистрация: 11.8.2011 Репутация: нет Всего: нет |
насколько я понимаю первая проблема в выделении памяти под объявление MSG, который объявлен, насколько я понимаю в winuser.h Так вот, неужели я буду что-то менять в этом файле? Или как тогда расширить пределы памяти, которая отводится под переменные функций? |
||||
|
|||||
| feodorv |
|
||||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 9 Всего: 45 |
Глянул код в проекте.... Замечаний масса..... Вот некоторые....
Да там особо не чему за пределы выходить)))
Что юникод, что нет, всё едино
Невиданная жестокость
Тут бы проверить, а стоИт ли вообще это делать:
Ну и, соответственно, всё это проинициализировать... И не так:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||||||
|
|||||||||||||
| GremlinProg |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2706 Регистрация: 9.8.2005 Где: Тюмень Репутация: 99 Всего: 106 |
эта ошибка системная, очень распространенная, спорить тут не о чем, т.е. выход за пределы блока - точно есть я только не понял, почему поднято именно это исключение, т.к. в данном случае - это выход за пределы массива при чтении: в WordCount передается указатель на 1 символ, а читается fSize, я бы предположил возможность исключения типа Access violation, но не суть, вообще, странная запись:
p - локальная переменная в WndProc, т.е. ты на каждое сообщение резервируешь символ и не удаляешь его, я уже не говорю, что результат MapViewOfFile так же теряется при выходе из WndProc( ..., WM_CREATE, ... ), т.е. пытаться как-то использовать p после этого бессмысленно -------------------- "Гений всегда разумнее, чем умнее. Ум — это машина, разум — водитель этой машины." |
|||
|
||||
![]()
|
| Правила форума "C/C++: Системное программирование и WinAPI" | |
|
|
На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы . Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |