Ошибка isctype c

RRS feed

  • Remove From My Forums
  • Question

  • HI,

           I am getting an assertion in isctype.c  saying for expression (unsigned) c <=256   what could be the reason

    Kishore

Answers

  • It sounds like you might be passing in a value larger than 255 — this is not allowed for isctype.c.

All replies

  • It sounds like you might be passing in a value larger than 255 — this is not allowed for isctype.c.

  • Hi.

    Though this call is late I just encountered the same problem again; I guess 101st times now.

     As I see it, many developers seem to run into this problem and the statement that passing a value larger than 255 is not allowed for isctype.c may be correct so far but the circumstances that lead to it seem to be a problem made by Microsoft itself.

    E.g. I have a mutithreaded program in debug, i.e. compiled with _DEBUG and _MT compiler switches, and I use some of the isspace, isdigit, is… CRT functions in my program. All of these functions have a signature specifying to accept an integer as only parameter and therefore I claim to use it as integer to test whatever (unicode) character to be a digit, a space or whatsoever.

    Now, if I run this program testing any arabic, kyrillic, chinese character the beforementioned assertion will come up. In release the program will state a protection fault. If you take a look at the CRT implementation you will find that it is not supported for multithreading but still the CRT itself (not my program) refers it. So as a developer I have no chance to work around it (and it really should not be my task to work around it).

    #if !defined (_MT) || defined (_DEBUG)
    int __cdecl _chvalidator(
            int c,
            int mask
            )
    {
            _ASSERTE((unsigned)(c + 1) <= 256);
            return ( _pctype[c] & mask);
    }

    Addenum:
    There may be of course the possibility to use the isw… functions but I am not quite sure if these are supported in the ANSI standard — and therefore may not be available on non-Windows platform compilers.

    Regards
     Frank

    • Proposed as answer by

      Wednesday, June 18, 2008 2:09 PM

    • Edited by
      Frank2068
      Wednesday, June 18, 2008 2:53 PM
      added addenum

  • Or less than -1, which is perfectly allowed for char. Try ‘я’ char(0xff).

I encountered this assertion in the development of the project some time ago. After reading a lot of information on the Internet, there is still no result. Most of the processing methods are:

Set the project -> Configuration Properties -> C / C + ± > Language -> Default Char unsigned, select Yes (/J)

This operation changes the default char type in the project to unsigned char (unsigned char), but this method does not work in the current VS2010. The current VS2010 does not have this option, and I am not sure about the default char type of the project. Whether the change will have other effects on my project, so I did not use this method.

Debugging for a long time found that my program called isspace (determine whether the character is a space), isprint (determine whether it is a printed character), isalnum (determine whether the character is a number), isdigit function, these functions in isctype.c, by viewing Isctype.c implementation source code found:

	extern "C" int __cdecl _chvalidator(int const c, int const mask)
{
    _ASSERTE(c >= -1 && c <= 255);
    return _chvalidator_l(nullptr, c, mask);
}

extern "C" int __cdecl _chvalidator_l(_locale_t const locale, int const c, int const mask)
{
    _ASSERTE(c >= -1 && c <= 255);
    
    _LocaleUpdate locale_update(locale);

    int const index = (c >= -1 && c <= 255) ? c : -1;

    return locale_update.GetLocaleT()->locinfo->_public._locale_pctype[index] & mask; 
}

Since my project default char is a signed type, its value range is [-128 ~ 127], when the passed characters exceed 127 (may be Chinese), then the char type value overflows to a negative number, and when called When the function is reached, the assertion _ASSERTE(c> = -1 && c <= 255) is triggered.

Solution:
When calling these functions, the argument is first forced to an unsigned char type (value range 0~255)

eg: isprint((unsigned char) c);

Sheffs

1 / 1 / 0

Регистрация: 31.05.2013

Сообщений: 14

1

Программа не обрабатывает кириллицу

31.05.2013, 02:15. Показов 3081. Ответов 9

Метки нет (Все метки)


Студворк — интернет-сервис помощи студентам

Всем привет. У меня такая проблема. Программа не хочет обрабатывать кириллицу. К примеру, у меня задача, подсчитать в последнем слове текста количество буквы «к». Если я ввожу текст на английском и ищу букву «k», то все нормально работает. Если же я ввожу русский текст и ищу букву «к», то программа выдает ошибку (скрин выложил ниже ).
Использую

C++
1
OemToAnsi(,):

из библиотеки

C++
1
#include <windows.h>

p.s. пусть вас не пугает список библиотек, я всегда добавляю всего и побольше)))

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
#include <windows.h>
#include <clocale>
using namespace std;
int main()
{
setlocale(LC_CTYPE,"Russian");
    static char A[512];
    cout<<"Введите текст"<<endl;
    cin.getline(A, 512);
    OemToAnsi(A,A);
    int count = 0;
    for (int i = strlen(A)-1; !isspace(A[i]) && i >= 0; i--)
        if (A[i] == 'к') count++;
    printf("%sncount = %dn",A,count);
    _getch();
    return 0;
}

Миниатюры

Программа не обрабатывает кириллицу
 



0



26 / 26 / 17

Регистрация: 29.12.2010

Сообщений: 90

31.05.2013, 02:33

2

Какая строка в вашей программе 68я? (обратите внимание на описание ошибки)
Прошу прощения, понял, что 68я строка в isctype.c

Добавлено через 6 минут
Запустил под Code::Blocks — все работает.



0



Croessmah

Неэпический

17815 / 10586 / 2044

Регистрация: 27.09.2012

Сообщений: 26,627

Записей в блоге: 1

31.05.2013, 02:36

3

Либо запускайте в релизе, либо приводите к unsigned char символы при передаче си функциям:

C++
1
isspace((unsigned char)A[i])



0



Sheffs

1 / 1 / 0

Регистрация: 31.05.2013

Сообщений: 14

31.05.2013, 02:39

 [ТС]

4

Насколько я понял Code::Blocks это некая программа(возможно ошибаюсь), но этой программы, к сожалению, нету у преподавателя
Только Visual c++ 2008, увы.
Порылся тут на форуме в подобных темах, вставлял приведенные варианты, не помогало. Может быть, конечно, криво вставлял.
В этой программе, почему то, все прекрасно читает и обрабатывает.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <cstring>
#include <sstream>
#include <conio.h>
#include <stdio.h>
#include <windows.h>
#include <clocale>
 
using namespace std;
int main()
{
setlocale(LC_CTYPE,"Russian");
char str[256],temp[256];
cout<<"Введите текст"<<endl;
cin.getline(str, 256);
OemToAnsi(str,str);
puts("nВведенная строка:"); puts(str);
int l=strlen(str),i,n=0,min,max;
istringstream ist(str);
ist>>temp;
min=max=strlen(temp);
while(ist>>temp)
{
if (strlen(temp)>max) 
max=strlen(temp);
if (strlen(temp)<min) 
min=strlen(temp);
}
cout<<"Длинна самого длинного слова:"<<max<<endl<<"Длина самого короткого слова:"<<min<<endl;
_getch();
return 0;
}



0



Неэпический

17815 / 10586 / 2044

Регистрация: 27.09.2012

Сообщений: 26,627

Записей в блоге: 1

31.05.2013, 02:43

5

Цитата
Сообщение от Sheffs
Посмотреть сообщение

В этой программе, почему то, все прекрасно читает и обрабатывает.

Здесь нет функций на подобии isspace,isdigit,isalpha и т.д., поэтому и работает.
Ваш код в шапке так же будет работать в релиз сборке. Да и в дебаге можно нажать «продолжить», либо как я написал уже привести аргумент к unsigned char



1



Nikoys

26 / 26 / 17

Регистрация: 29.12.2010

Сообщений: 90

31.05.2013, 02:50

6

Эта ошибка работает внутри Visual Studio, у меня тоже сработала эта ошибка. Хотя, в принципе, под Code::Blocks работает.
Опытным путем установлено, что вылетает программа на цикле, и не зависит от setlocale и OemToAnsi. Почему-то ей просто не нравятся русские буквы. Возможно, неправильный перевод происходит, и номер символа вылетает за границы -1…255.

Добавлено через 1 минуту

Цитата
Сообщение от Croessmah
Посмотреть сообщение

Либо запускайте в релизе, либо приводите к unsigned char символы при передаче си функциям:

C++
1
isspace((unsigned char)A[i])

только хотел написать, что выбивает на isspace. Что ж, вот где собака зарыта. Буду и сам на будущее знать.



0



1 / 1 / 0

Регистрация: 31.05.2013

Сообщений: 14

31.05.2013, 02:52

 [ТС]

7

Croessmah, Благодарю. Заработало. Можно поинтересоваться, собственно, в чем волшебство? в чем была проблема?



0



26 / 26 / 17

Регистрация: 29.12.2010

Сообщений: 90

31.05.2013, 02:52

8

Sheffs, Code::Blocks — другое IDE для С++. Только, в отличие от Visual Studio, в основе лежит компилятор GCC.



0



1500 / 1146 / 165

Регистрация: 05.12.2011

Сообщений: 2,279

31.05.2013, 03:07

9

это не ошибка компилятора. это такая реализация стандартной библиотеке, в частности той функции, откуда вылетает ассерт. его туда намеренно поставили, чтобы разработчики обратили внимание на то, что их код как-то неправильно использует функцию. как такое получилось мне непонятно. нужно дебажить. проверка такая там:
_ASSERTE((unsigned)(c + 1) <= 256);
т.е. переданный в функцию символ выходит за пределы диаппазона [0…255]. например каким-то макаром на обработку попали чары с отрицательными значениями.



0



Croessmah

Неэпический

17815 / 10586 / 2044

Регистрация: 27.09.2012

Сообщений: 26,627

Записей в блоге: 1

31.05.2013, 03:08

10

Цитата
Сообщение от Sheffs
Посмотреть сообщение

в чем была проблема?

Потому что вот что стоит в isctype.c

C++
1
_ASSERTE(c >= -1 && c <= 255);
C++
1
_ASSERTE(( unsigned )(c + 1) <= 256);



0



IT_Exp

Эксперт

87844 / 49110 / 22898

Регистрация: 17.06.2006

Сообщений: 92,604

31.05.2013, 03:08

10


Форум программистов Vingrad

Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы
Создание опроса
> проблема при отладке, Debug assertion Failed  

V

   

Опции темы

aleknek
Дата 9.12.2007, 18:46 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Не могу нормально отладить программу! Вылетает  сообщение:

    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;
}

Это сообщение отредактировал(а) aleknek — 9.12.2007, 19:23

PM MAIL   Вверх
JackYF
Дата 9.12.2007, 19:30 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

полуавантюрист
****

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

Репутация: 18
Всего: 162

На какой строке исходного кода?

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

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

Цитата(aleknek @  9.12.2007,  18:46 Найти цитируемый пост)
Вылетает  сообщение:

———————

Пожаловаться на меня как модератора можно здесь.

PM MAIL Jabber   Вверх
aleknek
Дата 9.12.2007, 20:56 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

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

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

PM MAIL   Вверх
JackYF
Дата 9.12.2007, 21:02 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

полуавантюрист
****

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

Репутация: 18
Всего: 162

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

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

———————

Пожаловаться на меня как модератора можно здесь.

PM MAIL Jabber   Вверх
zkv
Дата 10.12.2007, 09:09 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

****

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

Репутация: 26
Всего: 92

судя по всему вылетает на isalnum(), локаль надо советскую поставить  smile 

PM MAIL   Вверх
Random13
Дата 10.12.2007, 09:14 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Шустрый
*

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

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

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

PM MAIL   Вверх
zkv
Дата 10.12.2007, 09:27 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

****

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

Репутация: 26
Всего: 92

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

это TCHAR версия, ссылка

PM MAIL   Вверх
aleknek
Дата 15.12.2007, 19:04 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

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

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

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

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

PM MAIL   Вверх
crazy_hand
Дата 15.12.2007, 19:24 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Код
char *setlocale(
   int category,
   const char *locale 
);

Для русской локали это выглядит примерно так:

Код
setlocale(LC_ALL, "rus");

смотри  MSDN.

PM MAIL ICQ   Вверх
aleknek
Дата 15.12.2007, 19:47 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

Цитата(zkv @  10.12.2007,  09:09 Найти цитируемый пост)
судя по всему вылетает на isalnum(), локаль надо советскую поставить
Цитата(aleknek @  9.12.2007,  18:46 Найти цитируемый пост)
setlocale(LC_CTYPE,».1251″);
setlocale(LC_MONETARY,».1251″);

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

Это сообщение отредактировал(а) aleknek — 15.12.2007, 19:47

PM MAIL   Вверх
baldina
Дата 15.12.2007, 20:19 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Эксперт
****

Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 32
Всего: 101

Тут две проблемы: 

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, что касается циклов там все в порядке, так как завершающий » однозначно не 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]);

PM MAIL   Вверх
aleknek
Дата 16.12.2007, 01:08 (ссылка)
| (нет голосов)
Загрузка ... Загрузка …




Быстрая цитата

Цитата

Новичок

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

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

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

PM MAIL   Вверх



















Ответ в темуСоздание новой темы
Создание опроса
Правила форума «С++:Общие вопросы»
Earnest
Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл
    черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе — для этого существует «Центр Помощи».
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением,
Earnest
Daevaorn

 

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

I am working on writing a compiler for a school project, and this assignment calls for me to print the tokens of a text file to the console window. I want to make it clear I do not want my homework done for me.

I have been working with this stupid function that iterates through the file, and concatenates a char or a c-string value (my tutor was vague on this part of his instructions…) to a string variable named «token.» I can work through the first line of the file fine, which is «main()», but when I try and access the next line I get 1 of two errors. The first is a string subscript out of range error, though I think this was because I was trying to access part of a string array that didn’t exist. The most prevalent error I am getting is a debug assertion error:

Debug Assertion Failed Final.exe
File:f:ddvctoolscrt_bldself_x86crtsrcisctype.c Expression:
(unsigned)(c+1) <= 256

I have included my function and its associated header file. Nothing is going on in main except a function call. If at all possible, could you see what I am failing to see. I realize that my code structure is poor, I won’t lie (I am in school after all). So, any comments, criticism, and suggestions are very welcome. And always,thank you for any and all time.

.CPP File (As it is now)

    #include <iostream> 
    #include <string>

    using namespace std; 

    void tokenWork::openFile()
    {
        fileName = "test.txt"; 

        source.open(fileName);

        if(!source.is_open())
        {
       cout << "Cannot find file " << endl; 
        }
    }

    void tokenWork::traveseLine()
    {

    pos = 0; 
    while (!source.eof())
    {  
          getline(source,myLine); 
          int length = myLine.length(); 
          letters = new char[length];
          myLine.copy(letters,length); 

          c = letters[pos]; 

          if (isalpha(c))
             token = token + myLine[pos]; 
          else if (isdigit(c))
             token = token + letters; 
          else 
          {
             cout << token << endl; 
             token = ""; 
          }

          if (c == '{' || c == '}' || c == '+' || c == '=' || myLine[pos] == '(' || c == ')' || c == ';')
                cout << myLine[pos] << endl;  
          c = letters[pos++]; 
    }
}

.h file

    #ifndef H_LEX
    #define H_LEX

    #include <string> 
    #include <iostream> 
    #include <fstream> 

    using namespace std; 

    class tokenWork
    {
    public: 
    std::string fileName; 
    std::string myLine; 
    std::string token; 

    int pos; 
    int length; 
    int c;

    char *letters; 

    ifstream source; 

    void openFile(); 
    void traveseLine(); 
    void closeFile(); 

};

    #endif 

Понравилась статья? Поделить с друзьями:
  • Ошибка is not a valid guid value
  • Ошибка is not a valid floating point value
  • Ошибка is an invalid float
  • Ошибка irql not less or equal как исправить
  • Ошибка irql not less or equal windows 11