Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > работа со спроецированным файлом


Автор: wallstreet 28.4.2012, 17:16
Всем дообрый день.
Передо мной стоит задача посчитать символы и слова в тектовом файле, предварительно спроецированным в память.
Как пишут учебники, функция MapViewOfFile() проецирует файл на зарезервированное пространство и возвращает указатель
на начало области памяти "проекции файла" с которым можно работать как с обычным одномерным массивом.
Соответственно сразу рождается идея обычным циклом пробежаться по всем символам и понаходить пробелы + 1. Так
мы найдем кол-во слов.  А вот кол-во символов посчитать мне, поидее, должна помочь функция
GetFileSize(), однако она возвращает DWORD.

Соственно вопросы:
1) Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла?
2) Как конвертировать DWORD в int или какой функцией можно из значения переменной DWORD сделать строку?
 

Автор: feodorv 29.4.2012, 01:46
Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
однако она возвращает DWORD

Неужели этот так страшно? DWORD - сокращение от "double word" - "двойное слово" (4-х байтовая переменная). 

А можно и заглянуть в windef.h и увидеть такое:
Код

typedef unsigned long       DWORD;

То есть это, действительно, тип для 4-х байтовой беззнаковой переменной. Для win32 и win64 совпадает с "unsigned int". Поэтому вопрос
Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
Как конвертировать DWORD в int

отпадает сам собой. 


Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
GetFileSize(), однако она возвращает DWORD.

Внимательный осмотр вызова GetFileSize() показывает, что "она" возвращает не одно значение DWORD, а целых два smile 


Цитата(wallstreet @  28.4.2012,  18:16 Найти цитируемый пост)
Немного непонятно что является началом области памяти "проекция файла", первый символ спроецированного файла?

Гм. 
Цитата

LPVOID MapViewOfFile(
  HANDLE hFileMappingObject,   // handle to file-mapping object
  DWORD dwDesiredAccess,       // access mode
  DWORD dwFileOffsetHigh,      // high-order DWORD of offset
  DWORD dwFileOffsetLow,       // low-order DWORD of offset
  SIZE_T dwNumberOfBytesToMap  // number of bytes to map
);

LPVOID:
Код

typedef void far            *LPVOID;

То есть фактически LPVIOD есть "void *", указатель на память с проекцией файла. Работать с void * побайтово не очень удобно, но никто нам не мешает сделать так:
Код

unsigned char *mem = (unsigned char *) MapViewOfFile( ... );

И работайте себе (относительно) спокойно с mem как массивом байт...

Автор: Dem_max 30.4.2012, 10:11
или так
Код

int *mem = (int *) MapViewOfFile( ... );
int i = mem[10];

short *mem = (short *) MapViewOfFile( ... );
int i = short[10];

BYTE *mem = (BYTE *) MapViewOfFile( ... );
mem+=10;
BYTE b = *mem;

Автор: wallstreet 8.5.2012, 13:06
Цитата(feodorv @  29.4.2012,  01:46 Найти цитируемый пост)
То есть это, действительно, тип для 4-х байтовой беззнаковой переменной. Для win32 и win64 совпадает с "unsigned int".


при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то?

Вобщем опишу более детально на чем застопорился. Создал функцию которая считает слова в тексте, а кол-фо символов, включая пробелы буду определять функцией GetFileSize().
Проецирую файл:
Код

static HANDLE hFile, hFileMap;
static DWORD fSize;
TCHAR *p;
static RECT rt;
int *wCount, i, *q;
TCHAR *str;
case WM_CREATE:
        hFile = CreateFile(_T("My.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if(hFile != INVALID_HANDLE_VALUE)
        {
            fSize = GetFileSize(hFile, NULL);
            hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, fSize, NULL);
            if(hFileMap)
                p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
            break;
        }


вот так формирую строку и вывожу данные в WM_PAINT:
Код

_stprintf(str, _T("Word count = %I64d\n Simbols count = %I64d\n"), WordCount(p, fSize), SimbolsCount(fSize));
TextOut(hdc, 0, 0, str, fSize);


функция считающая слова и символы:
Код

int WordCount(TCHAR *pStr, unsigned int fSize){
int i, count;
for(i=1; i<fSize; i++)
{
    if(*pStr == ' ')
                    count++;
}
return count + 1;
}

int SimbolsCount(unsigned int fSize){

return fSize;
}


Мне кажется что я все делаю неправильно. Укажите с чего начинать исправлять ситуацию?
Кстати непонятно что значит плохой указатель (Bad Ptr):
user posted image
ссылка на проект http://zalil.ru/33200790

Автор: feodorv 9.5.2012, 01:26
Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
при инициализации переменной x типа unsigned int значением переменной y типа DWORD результат получается раскодированый какой-то. Число 12 превращается в 3435973836, это в каком формате то?

Ну, если печатать так:
Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
"Word count = %I64d\n Simbols count = %I64d\n"

величины, которые объявлены как int, то, да, 12 может превратиться во что угодно. Намёк: 4 байта = 32 битам, никак не 64.


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
int SimbolsCount(unsigned int fSize){
return fSize;
}

Ну и? А где fSize / sizeof(TCHAR)?


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
WordCount(p, fSize)

И почему fSize, а не WordCount(p, SimbolsCount(fSize))?
И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот?

По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно:
Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
int WordCount(TCHAR *pStr, unsigned int fSize)



Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
    if(*pStr == ' ')
                    count++;

Здесь точно ' ', даже для UNICODE версии программы?
А если два пробела подряд? А если табуляция или, не дай Бог, перевод строки? smile 


Цитата(wallstreet @  8.5.2012,  14:06 Найти цитируемый пост)
Кстати непонятно что значит плохой указатель (Bad Ptr):

Это значит указатель, который указывает на регион памяти, не переданный данному процессу. Процессу принадлежат его 4 гига (или больше для 64-х битных ОС), но не вся эта память является действительной (зарезервированной процессом). Иначе говоря, p указывает непонятно куда. Почему 0xcccccccc? Потому что:
Цитата
0xCC, 0xCCCCCCCC — The /GX Microsoft Visual C++ compiler option initialises all local variables not explicitly initialised by the program. It fills all memory used by these variables with 0xCC, 0xCCCCCCCC.
.
 smile 

Автор: Albor 11.5.2012, 11:17
Цитата(wallstreet @  8.5.2012,  12:06 Найти цитируемый пост)
функция считающая слова и символы:
код C++

int WordCount(TCHAR *pStr, unsigned int fSize){
int i, count;
for(i=1; i<fSize; i++)
{
    if(*pStr == ' ')
                    count++;
}
return count + 1;
}
int SimbolsCount(unsigned int fSize){
return fSize;
}

Ишь, как просто слова считать... smile А если в тексте пропущен пробел после запятой, например, (про несколько пробелов уже писали). Слово начинается с буквы и буквой заканчивается - вот определяющий фактор подсчёта, ну и определиться, считать ли за слова числа.

Автор: wallstreet 14.5.2012, 18:01
Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Намёк: 4 байта = 32 битам, никак не 64.

я понял, исправил на:
Код

_stprintf(str, _T("Word count = %i\n Simbols count = %i\n"), WordCount(p, SimbolsCount(fSize)), SimbolsCount(fSize));



Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Ну и? А где fSize / sizeof(TCHAR)?

функция 
Код

fSize = GetFileSize(hFile, NULL);

может я в чем-то заблуждаюсь, но возвращает правильное кол-во символов в файле.
user posted image


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
И откуда Вы знаете, что исследуемый файл находится в UNICODE, а не в ASCII? Или наоборот?

Честно признаться, я знаю в чем отличие между двумя этими кодировками но как определить кодировку в которой находится файл не имею понятия. Может по символам которые в 256 битную таблицу ASCII не влазят пробежаться циклом, или как? Вообще я думал что если я читаю текстовый файл и при этом использую расширенную кодировку в разных функциях работы с файлом, то все будет получаться, т.к. UNICODE содержит все символы и буквы кодировки ASCII.


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
По крайней мере, в WordCount отправляется число байт файла, а содержимое файла обрабатывается по-символьно:Цитата(wallstreet @  8.5.2012,  14:06 )int WordCount(TCHAR *pStr, unsigned int fSize)

Хммм... в смысле число байт? т.е. в виде двоичной системы счисления? В таком случаем с помощью какой функции можно конвертировать данные в символы? Или каким методом?


Цитата(feodorv @  9.5.2012,  01:26 Найти цитируемый пост)
Это значит указатель, который указывает на регион памяти, не переданный данному процессу

в объявлении:
Код

TCHAR *p = new TCHAR;

помогло.


Цитата(Albor @  11.5.2012,  11:17 Найти цитируемый пост)
Слово начинается с буквы и буквой заканчивается - вот определяющий фактор подсчёта

Я понял, переделал на вот так:
Код

int WordCount(TCHAR *pStr, unsigned int fSize){
    int i, j, y, count = 0;
    TCHAR *abc[26] = {_T("a"), _T("b"), _T("c"), _T("d"), _T("e"), _T("f"), // массив букв
                      _T("g"), _T("h"), _T("i"), _T("j"), _T("k"), _T("l"), 
                      _T("m"), _T("n"), _T("o"), _T("p"), _T("q"), _T("r"), 
                      _T("s"), _T("t"), _T("u"), _T("v"), _T("w"), _T("x"), 
                      _T("y"), _T("z")};
    TCHAR *simb[7] = {_T("."), _T(","), _T(";"), _T(":"), _T("!"), _T("?"), // массив символов 
                      _T(" ")};
    for(i=0; i<fSize; i++)                                                  // бежим по символам текста
    { 
        for(j=0; j<26; j++)                                                 // бежим по буквам и пытаемся
            if(*pStr == *abc[j])                                            // узнать, неявляется ли символ началом слова, т.е. буквой
                for(; i<fSize; i++)                                         // если является, то идем дальше по символам текста
                { 
                    for(y=0; y<6; y++)                                      // пока после букв нам не встретится знак припинания или пробел
                        if(*pStr == *simb[y])
                            count++;                                        // если встретился увеличиваем счетчик.
                }
    }
    return count;
}

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

всех участвующих благодарю за бесценный вклад в мои знания.
чуть не забыл ->http://zalil.ru/33235995

Автор: volatile 15.5.2012, 00:14
Цитата(wallstreet @  14.5.2012,  18:01 Найти цитируемый пост)
int WordCount(TCHAR *pStr, unsigned int fSize){
    int i, j, y, count = 0;
    TCHAR *abc[26] = {_T("a"), _T("b"), _T("c"), _T("d"), _T("e"), _T("f"), // массив букв
                      _T("g"), _T("h"), _T("i


боже мой, ... ...

Добавлено через 12 минут и 45 секунд
wallstreet, это был ацкий кот!

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

Ну и алгоритм упрощается, 

Код

int WordCount (TCHAR *pStr, unsigned int fSize)
{
    unsigned count = 0;
    int prev_alpha = 0; // булева переменная, истина, если предыдущий символ был буквой.
    for (unsigned i = 0; i < fSize; ++i)
    {
       int now_alpha = _istalpha (pStr [i]); // Текущий символ есть буква?
       count += now_alpha && !prev_alpha;    // Если текущий символ буква, и предыдущий был НЕ буква, то прибавляем счетчик
       prev_alpha = now_alpha;               // Текущий символ становится прошлым.
    }
    return count;
}

Задолбался писать комментарии...

Автор: volatile 15.5.2012, 00:29
Вообще хорошо бы точное определение, что считать словом.
Если например вы хотите набор цифр и букв идущих подряд считать одним словом, то
 _istalpha()  нужно заменить на _istalnum()

Автор: wallstreet 16.5.2012, 11:54
Спасибо, то что надо!  smile 
Проект компилируется и отрисовывает правильный результат, но после этого выскакивают ошибки с которыми не могу справиться.
user posted image
Подскажите в связи с чем эти ошибки и как я могу их устранить?

http://zalil.ru/33247673

Автор: volatile 16.5.2012, 23:37
Цитата(wallstreet @  16.5.2012,  11:54 Найти цитируемый пост)
выскакивают ошибки

Какие ошибки?

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

Автор: GremlinProg 17.5.2012, 06:41
судя по содержимому окна output, край которого все же видно, это повреждение кучи,
которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен

Автор: wallstreet 17.5.2012, 16:56
Цитата(volatile @  16.5.2012,  23:37 Найти цитируемый пост)
лучше бы лог ошибок запостили



Цитата

Critical error detected c0000374
Windows has triggered a breakpoint in HomeWork6.9.exe.

This may be due to a corruption of the heap, which indicates a bug in HomeWork6.9.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while HomeWork6.9.exe has focus.

The output window may have more diagnostic information.





Цитата(GremlinProg @  17.5.2012,  06:41 Найти цитируемый пост)
в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен 

насколько я понимаю первая проблема в выделении памяти под объявление MSG, который объявлен, насколько я понимаю в winuser.h
Так вот, неужели я буду что-то менять в этом файле? Или как тогда расширить пределы памяти, которая отводится под переменные функций?

Автор: feodorv 17.5.2012, 20:15
Глянул код в проекте.... Замечаний масса..... Вот некоторые....

Цитата(GremlinProg @  17.5.2012,  07:41 Найти цитируемый пост)
которое скорее всего говорит о том, что в каком-то месте программы произведена запись блока памяти за пределы, на которые он был распределен 

Да там особо не чему за пределы выходить))) 


Цитата

int SimbolsCount(unsigned int fSize){

    return fSize;
}

Что юникод, что нет, всё едино  smile 


Цитата

    switch (message)
    {
    case WM_CREATE:
                ...
  DestroyWindow(hWnd);
  break;

Невиданная жестокость  smile  smile  smile  


Цитата

    case WM_DESTROY:
  UnmapViewOfFile(p);
  CloseHandle(hFileMap);
  CloseHandle(hFile);
                ...

Тут бы проверить, а стоИт ли вообще это делать:
Код

if( p != NULL ) ...
if( hFileMap != NULL ) ...
if( hFile != INVALID_HANDLE_VALUE ) ...

Ну и, соответственно, всё это проинициализировать... И не так:
Цитата

        ...
    TCHAR *p = new TCHAR;
         ...
    if(hFileMap)
    p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
         ...
  case IDM_EXIT:
    delete p;

         ...

Автор: GremlinProg 18.5.2012, 07:25
Цитата(feodorv @  17.5.2012,  22:15 Найти цитируемый пост)
Да там особо не чему за пределы выходить))) 

эта ошибка системная, очень распространенная, спорить тут не о чем, т.е. выход за пределы блока - точно есть

я только не понял, почему поднято именно это исключение, т.к. в данном случае - это выход за пределы массива при чтении: в WordCount передается указатель на 1 символ, а читается fSize,

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

вообще, странная запись:
Цитата(wallstreet)

TCHAR *p = new TCHAR;

p - локальная переменная в WndProc, т.е. ты на каждое сообщение резервируешь символ и не удаляешь его,
я уже не говорю, что результат MapViewOfFile так же теряется при выходе из WndProc( ..., WM_CREATE, ... ), т.е. пытаться как-то использовать p после этого бессмысленно

Автор: feodorv 18.5.2012, 10:02
Цитата(GremlinProg @  18.5.2012,  08:25 Найти цитируемый пост)
эта ошибка системная, очень распространенная

Сам её совершал неоднократно)))

Цитата(GremlinProg @  18.5.2012,  08:25 Найти цитируемый пост)
выход за пределы блока - точно есть

Я имел в виду, что в коде записи в память нет, всё рид-онли smile А так-то))))


Цитата(GremlinProg @  18.5.2012,  08:25 Найти цитируемый пост)
в WordCount передается указатель на 1 символ, а читается fSize,

Мда. Казалось бы, начало неплохое, если CreateFile, GetFileSize, CreateFileMapping и MapViewOfFile отрабатывают без ошибок (что не очевидно):
Цитата

    case WM_CREATE:
  hFile = CreateFile(_T("My.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if(hFile != INVALID_HANDLE_VALUE)
  {
    fSize = GetFileSize(hFile, NULL);
    hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, fSize, NULL);
    if(hFileMap)
    p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
    break;
  }
  countW = WordCount(p, fSize);
  countT = fSize;

Остро нужен контроль ошибок. 
Кроме того, если ни hFile, ни hFileMap (кроме как в высвобождении ресурсов) более не используются, почему бы их здесь же не освободить (и забыть про них)?
Кроме того:
Цитата
    unsigned int countW, countT;
 как и p тоже не static.


Однако, в WM_PAINT... 
Цитата

  _stprintf(str, _T("Word count = %i\n Simbols count = %i\n"), WordCount(p, SimbolsCount(fSize)), SimbolsCount(fSize));

При этом: 
Цитата(wallstreet @  16.5.2012,  12:54 Найти цитируемый пост)
отрисовывает правильный результат
 smile 


Цитата(wallstreet @  14.5.2012,  19:01 Найти цитируемый пост)
в объявлении:

1: TCHAR *p = new TCHAR;

помогло.

Жуть... Ну и лекарство...


Такой код
Цитата

TCHAR *p = new TCHAR;
...
UnmapViewOfFile(p);

разрушить кучу вполне способен...

Автор: GremlinProg 18.5.2012, 10:18
Цитата(feodorv @ 18.5.2012,  12:02)
Такой код
Цитата

TCHAR *p = new TCHAR;
...
UnmapViewOfFile(p);

разрушить кучу вполне способен...

ну, в данном случае, куча портится раньше вызова UnmapViewOfFile,
так что все равно не понятно, где она успела это сделать

Автор: feodorv 18.5.2012, 10:38
Цитата(GremlinProg @  18.5.2012,  11:18 Найти цитируемый пост)
так что все равно не понятно, где она успела это сделать

Тогда ждём от wallstreet исправлений и дальнейших приключений  smile 

Автор: wallstreet 21.5.2012, 15:22
Пока пришел вот к этому результату и дальше сдвинуться не могу никак.
Код

int WordCount(TCHAR *pStr, unsigned int fSize)
{
    unsigned count = 0;
    int prev_alpha = 0;
    for(unsigned i=0; i<fSize; ++i)
    {
        int now_alpha = _istalnum(pStr[i]);
        count +=now_alpha && !prev_alpha;
        prev_alpha = now_alpha;
    }
    return count;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    static HANDLE hFile, hFileMap;
    static DWORD fSize;
    static RECT rt;
    static TCHAR *str = new TCHAR;
    static TCHAR *p = 0;


    switch (message)
    {
    case WM_CREATE:
        hFile = CreateFile(_T("My.txt"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if(hFile != INVALID_HANDLE_VALUE)
        {
            fSize = GetFileSize(hFile, NULL);
            hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, fSize, NULL);
            if(hFileMap)
            {
                CloseHandle(hFile);
                p = (TCHAR*)MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
                CloseHandle(hFileMap);
            }
            break;
        }
        break;
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        GetClientRect(hWnd, &rt);
        hdc = BeginPaint(hWnd, &ps);
        if(*str)
        {
            _stprintf(str, _T("Word count = %i\nSimbols count = %i\n"), WordCount(p, fSize), fSize);
            DrawText(hdc, str, _tcslen(str), &rt, DT_LEFT);
        }
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        if(p!=NULL)
            UnmapViewOfFile(p);
        if(str!=NULL)
            delete str;
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

Прошу не судить строго и намекать потолще на суть ошибки.
Буду стараться все быстрее исправить.
Кстати сейчас уже ошибка выполнения выскакивает при попытке закрыть окно.
суть:
Цитата

First-chance exception at 0x77942a80 in HomeWork6.9.exe: 0xC0000005: Access violation reading location 0xdddddde1.
The program '[5648] HomeWork6.9.exe: Native' has exited with code 0 (0x0).

указывает на:
Код

return DefWindowProc(hWnd, message, wParam, lParam);

в разделе обработки сообщения WM_DESTROY

http://zalil.ru/33278423

Автор: feodorv 21.5.2012, 16:00
Цитата(wallstreet @  21.5.2012,  16:22 Найти цитируемый пост)
Прошу не судить строго и намекать потолще на суть ошибки.

Да мы добрые)))
Потолще... Гм, ну, разве что, взять и код переписать))))


Цитата(wallstreet @  21.5.2012,  16:22 Найти цитируемый пост)
    static HANDLE hFile, hFileMap;
    static DWORD fSize;
    static RECT rt;
    static TCHAR *str = new TCHAR;
    static TCHAR *p = 0;

Статики радуют глаз))) Кстати, Вы интересовались, чем статик от нестатик отличается?)))

Не радует глаз 
Цитата(wallstreet @  21.5.2012,  16:22 Найти цитируемый пост)
    static TCHAR *str = new TCHAR;

Цитата(wallstreet @  21.5.2012,  16:22 Найти цитируемый пост)
        if(*str)
        {
            _stprintf(str, _T("Word count = %i\nSimbols count = %i\n"), WordCount(p, fSize), fSize);

Для str памяти выделено всего на 1 символ!!! Вот это
Цитата(wallstreet @  21.5.2012,  16:22 Найти цитируемый пост)
_T("Word count = %i\nSimbols count = %i\n")

туда уже не влезает никак! И зачем if(*str)? Просто if(str) ещё понятно smile 

Вообще, зачем под str выделять память через new? Достаточно написать 
Код

TCHAR str[256];
 
То есть даже не статик, и не нужно потом возиться с высвобождением. Само объявление str можно даже перенести в WM_PAINT...

Добавлено через 2 минуты и 40 секунд
Вообще, код стал выглядеть намного лучше smile 
Но с юникодом мы ещё поборемся smile 

Автор: wallstreet 22.5.2012, 13:14
Цитата(feodorv @  21.5.2012,  16:00 Найти цитируемый пост)
Но с юникодом мы ещё поборемся   


с удовольствием!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)