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


Автор: aleknek 9.12.2007, 18:46
Не могу нормально отладить программу! Вылетает  сообщение:


    Debug assertion Failed
    Program: d:\проекты\указатель\debug\указатель.exe
    File: isctype.c
    Line: 68

    Expression: (unsigned)(c+1)<=256 

Смотрел файл isctype.c , не могу вычислить где ошибка ? 
  
Собственно сам код:
Код

// выделение слов из массива символов, вычисления с указателями
#include "stdafx.h"
#include"locale.h"
#include"ctype.h"
#include"string.h"
#include"iostream"
using namespace std;

bool GetWord (char* string, char* word, int& wordOffset);

int _tmain(int argc, _TCHAR* argv[])

{
    //________________________________________
    setlocale(LC_CTYPE,".1251");
    setlocale(LC_MONETARY,".1251");

   //_________________________________________

    const int bufferSize=255;
    char buffer [bufferSize+1];  // переменная для хранения всей строки
    char word   [bufferSize+1];  // переменная для хранения слова
    int wordOffset = 0;

    cout << "Введите строку \n";
    cin.getline(buffer,bufferSize);

    while(GetWord(buffer,word,wordOffset))
    {
        cout << "Got this word:" << word << endl;
    }

    return 0;
}


bool GetWord(char* string, char* word, int& wordOffset)

{
if (!string[wordOffset]) // определяет конец строки
return false;

char *p1, *p2;
p1=p2=string+wordOffset; // указатель на следующее слово

// удаляем ведущие пробелы
for(int i=0; i<(int)strlen(p1) && ! isalnum(p1[0]); i++)
p1 ++;

// проверка наличия слова
if (! isalnum(p1[0]))
return false;

// указатель р1 показывает начало следующего слова, также как и р2
p2=p1;

// перемещаем р2 в конец слова
while (isalnum(p2[0]))
p2++;

// р2 указывает на конец слова, а р1 на начало. Разность указателей показывает  длину слова.
int len= int(p2-p1);

// копируем слово в буфер.
strncpy(word,p1,len);

// и добавляем символ разрыва строки
word [len]='\ 0';

// ищем начало следующего слова
for (int i =int(p2-string); i<(int)strlen(string) && ! isalnum(p2[0]);i++)
p2++;

wordOffset=int(p2-string);
return true;
}



Автор: JackYF 9.12.2007, 19:30
На какой строке исходного кода?

Цитата(aleknek @  9.12.2007,  18:46 Найти цитируемый пост)
// перемещаем р2 в конец слова
while (isalnum(p2[0]))
p2++;

не проверяешь выход за слово. Возможно переполнение.
Цитата(aleknek @  9.12.2007,  18:46 Найти цитируемый пост)
Вылетает  сообщение:


Автор: aleknek 9.12.2007, 20:56
Цитата

не проверяешь выход за слово. Возможно переполнение.

Как организовать проверку выхода за слово ?

Автор: JackYF 9.12.2007, 21:02
Цитата(aleknek @  9.12.2007,  20:56 Найти цитируемый пост)
Как организовать проверку выхода за слово ? 

узнать strlen'ом длину и поставить в while дополнительное условие на счётчик операций (или на разницу указателей)

Автор: zkv 10.12.2007, 09:09
судя по всему вылетает на isalnum(), локаль надо советскую поставить  smile 

Автор: Random13 10.12.2007, 09:14
Интересно, а _tmain вместо обычного мэйн - это в какой среде пишеться в борланде что-ли ?
В борланде никогда не работал ?

Автор: zkv 10.12.2007, 09:27
Цитата(Random13 @  10.12.2007,  09:14 Найти цитируемый пост)
Интересно, а _tmain вместо обычного мэйн

это TCHAR версия, http://forum.vingrad.ru/faq/topic-173734.html

Автор: aleknek 15.12.2007, 19:04
Цитата(Random13 @  10.12.2007,  09:14 Найти цитируемый пост)
Интересно, а _tmain вместо обычного мэйн - это в какой среде пишеться в борланде что-ли ?
В борланде никогда не работал ? 

Пишется это все в Microsoft Visual Studio 2005



Цитата(zkv @  10.12.2007,  09:09 Найти цитируемый пост)
судя по всему вылетает на isalnum(), локаль надо советскую поставить

Как это сделать ?

Автор: crazy_hand 15.12.2007, 19:24
Код
char *setlocale(
   int category,
   const char *locale 
);

Для русской локали это выглядит примерно так:
Код
setlocale(LC_ALL, "rus");

смотри  http://msdn2.microsoft.com/ru-ru/default.aspx.

Автор: aleknek 15.12.2007, 19:47
Цитата(zkv @  10.12.2007,  09:09 Найти цитируемый пост)
судя по всему вылетает на isalnum(), локаль надо советскую поставить



Цитата(aleknek @  9.12.2007,  18:46 Найти цитируемый пост)
setlocale(LC_CTYPE,".1251");
setlocale(LC_MONETARY,".1251");

А это разве не русская локаль ??

Автор: baldina 15.12.2007, 20:19
Тут две проблемы: 

1. т.к. приложение консольное, должна использоваться локаль 866.
Т.е. нужен setlocale(LC_CTYPE,".866"); Это для того что бы правильно отрабатывал isalnum для русских букв.

2. int isalnum(int) - на входе целое.
Ошибка такая:
Цитата

Expression: (unsigned)(c+1)<=256 


понятно, что все буковки с кодом больше 127 представляются ... как отрицательные! и (unsigned)(c+1) значительно больше 256.

вывод - использовать unsigned char всместо char в коде либо выставить в свойствах компиляции 
Language->Default Char Unsigned->Yes

Кстати там еще ошибка в коде - '\ 0', т.е. пробел между \ и 0

Добавлено через 1 минуту и 47 секунд
JackYF, что касается циклов там все в порядке, так как завершающий '\0' однозначно не isalnum

Добавлено через 12 минут и 21 секунду
Вообще полезно использовать unsigned char, если предпологается хранить там строки с родным нам русским языком. Во избежание многих проблем.
пример:
Код

  char str1[] = { 'Z', 'Я' };
  unsigned char str2[] = { 'Z', 'Я' };
  std::boolalpha (std::cout);
  std::cout << (str1[0] < str1[1]) << " vs " << (str2[0] < str2[1]);

Автор: aleknek 16.12.2007, 01:08
Всем огромное спасибо, проблема решилась при подключении 866 локали и изменении свойств компиляции.  

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