| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Системное программирование и WinAPI > работа со спроецированным файлом |
| Автор: wallstreet 28.4.2012, 17:16 |
| Всем дообрый день. Передо мной стоит задача посчитать символы и слова в тектовом файле, предварительно спроецированным в память. Как пишут учебники, функция MapViewOfFile() проецирует файл на зарезервированное пространство и возвращает указатель на начало области памяти "проекции файла" с которым можно работать как с обычным одномерным массивом. Соответственно сразу рождается идея обычным циклом пробежаться по всем символам и понаходить пробелы + 1. Так мы найдем кол-во слов. А вот кол-во символов посчитать мне, поидее, должна помочь функция GetFileSize(), однако она возвращает DWORD. Соственно вопросы: 1) Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла? 2) Как конвертировать DWORD в int или какой функцией можно из значения переменной DWORD сделать строку? |
| Автор: Dem_max 30.4.2012, 10:11 | ||
или так
|
| Автор: wallstreet 8.5.2012, 13:06 | ||||||||
при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то? Вобщем опишу более детально на чем застопорился. Создал функцию которая считает слова в тексте, а кол-фо символов, включая пробелы буду определять функцией GetFileSize(). Проецирую файл:
вот так формирую строку и вывожу данные в WM_PAINT:
функция считающая слова и символы:
Мне кажется что я все делаю неправильно. Укажите с чего начинать исправлять ситуацию? Кстати непонятно что значит плохой указатель (Bad Ptr): ![]() ссылка на проект http://zalil.ru/33200790 |
| Автор: feodorv 9.5.2012, 01:26 | ||||
Ну, если печатать так: величины, которые объявлены как int, то, да, 12 может превратиться во что угодно. Намёк: 4 байта = 32 битам, никак не 64. Ну и? А где fSize / sizeof(TCHAR)? И почему fSize, а не WordCount(p, SimbolsCount(fSize))? И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот? По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно: Здесь точно ' ', даже для UNICODE версии программы? А если два пробела подряд? А если табуляция или, не дай Бог, перевод строки? Это значит указатель, который указывает на регион памяти, не переданный данному процессу. Процессу принадлежат его 4 гига (или больше для 64-х битных ОС), но не вся эта память является действительной (зарезервированной процессом). Иначе говоря, p указывает непонятно куда. Почему 0xcccccccc? Потому что:
|
| Автор: Albor 11.5.2012, 11:17 | ||
Ишь, как просто слова считать... |
| Автор: wallstreet 14.5.2012, 18:01 | ||||||||||||||||
я понял, исправил на:
функция
может я в чем-то заблуждаюсь, но возвращает правильное кол-во символов в файле. ![]()
Честно признаться, я знаю в чем отличие между двумя этими кодировками но как определить кодировку в которой находится файл не имею понятия. Может по символам которые в 256 битную таблицу ASCII не влазят пробежаться циклом, или как? Вообще я думал что если я читаю текстовый файл и при этом использую расширенную кодировку в разных функциях работы с файлом, то все будет получаться, т.к. UNICODE содержит все символы и буквы кодировки ASCII.
Хммм... в смысле число байт? т.е. в виде двоичной системы счисления? В таком случаем с помощью какой функции можно конвертировать данные в символы? Или каким методом?
в объявлении:
помогло.
Я понял, переделал на вот так:
но по всей видимости у меня действительно кракозябры вместо символов текста с которыми я сравниваю буквы из моего массива, соответственно ни одного совпадения по буквам не происходит поэтому счетчик нулевой. Данным примером я хочу показать принцип, с помощью которого, по моему мнению нужно решать задачу. Если я ошибаюсь прошу поправить. всех участвующих благодарю за бесценный вклад в мои знания. чуть не забыл ->http://zalil.ru/33235995 |
| Автор: volatile 15.5.2012, 00:14 | ||||
боже мой, ... ... Добавлено через 12 минут и 45 секунд wallstreet, это был ацкий кот! Я бы слова подсчитывал по следующему простому алгоритму. Если текущий символ - есь буква, а предыдущий был не буква, это есть начало слова. Конец ведь нам не нужен То что конец будет, (и причем всему, уже скоро) это аксиома. Даже если текст оборвется на середине слова, мы это слово обязаны засчитать. Ну и алгоритм упрощается,
Задолбался писать комментарии... |
| Автор: volatile 15.5.2012, 00:29 |
| Вообще хорошо бы точное определение, что считать словом. Если например вы хотите набор цифр и букв идущих подряд считать одним словом, то _istalpha() нужно заменить на _istalnum() |
| Автор: wallstreet 16.5.2012, 11:54 |
| Спасибо, то что надо! Проект компилируется и отрисовывает правильный результат, но после этого выскакивают ошибки с которыми не могу справиться. ![]() Подскажите в связи с чем эти ошибки и как я могу их устранить? http://zalil.ru/33247673 |
| Автор: volatile 16.5.2012, 23:37 |
Какие ошибки? лучше бы лог ошибок запостили, чем ничего незначащие картинки, и неочищенный проект на 11 метров. (у меня например нэт здесь очень медленный, и дорогой. и грузить своп вашего харда никакого желания нет.) |
| Автор: GremlinProg 17.5.2012, 06:41 |
| судя по содержимому окна output, край которого все же видно, это повреждение кучи, которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен |
| Автор: wallstreet 17.5.2012, 16:56 | ||||
насколько я понимаю первая проблема в выделении памяти под объявление MSG, который объявлен, насколько я понимаю в winuser.h Так вот, неужели я буду что-то менять в этом файле? Или как тогда расширить пределы памяти, которая отводится под переменные функций? |
| Автор: feodorv 17.5.2012, 20:15 | ||||||||||||
Глянул код в проекте.... Замечаний масса..... Вот некоторые....
Да там особо не чему за пределы выходить)))
Что юникод, что нет, всё едино
Невиданная жестокость
Тут бы проверить, а стоИт ли вообще это делать:
Ну и, соответственно, всё это проинициализировать... И не так:
|
| Автор: GremlinProg 18.5.2012, 07:25 | ||
эта ошибка системная, очень распространенная, спорить тут не о чем, т.е. выход за пределы блока - точно есть я только не понял, почему поднято именно это исключение, т.к. в данном случае - это выход за пределы массива при чтении: в WordCount передается указатель на 1 символ, а читается fSize, я бы предположил возможность исключения типа Access violation, но не суть, вообще, странная запись:
p - локальная переменная в WndProc, т.е. ты на каждое сообщение резервируешь символ и не удаляешь его, я уже не говорю, что результат MapViewOfFile так же теряется при выходе из WndProc( ..., WM_CREATE, ... ), т.е. пытаться как-то использовать p после этого бессмысленно |
| Автор: feodorv 18.5.2012, 10:02 | ||||||||||
Сам её совершал неоднократно))) Я имел в виду, что в коде записи в память нет, всё рид-онли
Мда. Казалось бы, начало неплохое, если CreateFile, GetFileSize, CreateFileMapping и MapViewOfFile отрабатывают без ошибок (что не очевидно):
Остро нужен контроль ошибок. Кроме того, если ни hFile, ни hFileMap (кроме как в высвобождении ресурсов) более не используются, почему бы их здесь же не освободить (и забыть про них)? Кроме того:
Однако, в WM_PAINT...
При этом: Жуть... Ну и лекарство... Такой код
разрушить кучу вполне способен... |
| Автор: GremlinProg 18.5.2012, 10:18 | ||||
ну, в данном случае, куча портится раньше вызова UnmapViewOfFile, так что все равно не понятно, где она успела это сделать |
| Автор: feodorv 18.5.2012, 10:38 |
Тогда ждём от wallstreet исправлений и дальнейших приключений |
| Автор: wallstreet 21.5.2012, 15:22 | ||||||
Пока пришел вот к этому результату и дальше сдвинуться не могу никак.
Прошу не судить строго и намекать потолще на суть ошибки. Буду стараться все быстрее исправить. Кстати сейчас уже ошибка выполнения выскакивает при попытке закрыть окно. суть:
указывает на:
в разделе обработки сообщения WM_DESTROY http://zalil.ru/33278423 |
| Автор: feodorv 21.5.2012, 16:00 | ||||||
Да мы добрые))) Потолще... Гм, ну, разве что, взять и код переписать))))
Статики радуют глаз))) Кстати, Вы интересовались, чем статик от нестатик отличается?))) Не радует глаз
Для str памяти выделено всего на 1 символ!!! Вот это туда уже не влезает никак! И зачем if(*str)? Просто if(str) ещё понятно Вообще, зачем под str выделять память через new? Достаточно написать
То есть даже не статик, и не нужно потом возиться с высвобождением. Само объявление str можно даже перенести в WM_PAINT... Добавлено через 2 минуты и 40 секунд Вообще, код стал выглядеть намного лучше Но с юникодом мы ещё поборемся |
| Автор: wallstreet 22.5.2012, 13:14 |
с удовольствием! |