- 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
-
Proposed as answer by
-
Or less than -1, which is perfectly allowed for char. Try ‘я’ char(0xff).
When I enter a password in my program below and press enter I get a debug
assertion error, specifically isctype.c line 56
Expression:(unsigned)(c+1) <= 256
Could someone help me get around this please?
Code:
int main()
{
int j=0;
char pass[100];
int upper=0, lower=0, digit=0, sc=0;
printf("Enter your password:n");
scanf("%s",&pass);
while(j!=' '){
if(isalpha(pass[j])){
if(isupper(pass[j])){
upper++;
}
else{
lower++;
}
}
else if(isdigit(pass[j])){
digit++;
}
else{
sc++;
}
j++;
}
if(upper==0||lower==0||digit==0||sc==0){
printf("Password must contain atleast one upper case, one lower case, one digit and a special character");
}
else{
printf("Good to go");
}
return 0;
_getch();
}
Sourav Ghosh
132k16 gold badges184 silver badges258 bronze badges
asked Jun 11, 2015 at 13:44
4
Replace
while (j!=' ')
by
while (pass[j] != 0)
You want to loop as long as pass[j]
is different from zero. Remember, strings are terminated by a zero.
answered Jun 11, 2015 at 13:56
JabberwockyJabberwocky
46.6k17 gold badges57 silver badges108 bronze badges
It looks like the problem in your code is
while(j!=' ')
which is checking j
against space (' '
) which is having ASCII value of 32 (decimal).
Essentially, you’re unconditionally using pass
array elements having index 0 to 31.
Then, pass
is an automatic local variable and you did not initialize it. It contains indeterminate value.
If, your input is less than 31 characters, the remaining element of pass
will remain uninitialized, and using them further (as the argument to is....()
family, here) may lead to undefined behaviour.
Solution: You don’t need to check for a space, (as %s
does not accept one). Instead you should check for the null terminator . Change your code to
scanf("%s",&pass);
toscanf("%99s",pass);
to avoid possible buffer overflow.while(j!=' ')
towhile(pass[j])
to loop until the string terminator null.
That said,
- using
_getch()
after unconditionalreturn
statement does not make any sense. You can straight-away remove that_getch()
. - The recommended signature of
main()
isint main(void)
.
answered Jun 11, 2015 at 13:54
Sourav GhoshSourav Ghosh
132k16 gold badges184 silver badges258 bronze badges
Сегодня мне пришел баг-репорт от пользователя Debian, который скормил какую-то ерунду в утилиту scdoc и получил SIGSEGV
. Исследование проблемы позволило мне провести отличное сравнение между musl libc
и glibc
. Для начала посмотрим на стектрейс:
==26267==ERROR: AddressSanitizer: SEGV on unknown address 0x7f9925764184
(pc 0x0000004c5d4d bp 0x000000000002 sp 0x7ffe7f8574d0 T0)
==26267==The signal is caused by a READ memory access.
0 0x4c5d4d in parse_text /scdoc/src/main.c:223:61
1 0x4c476c in parse_document /scdoc/src/main.c
2 0x4c3544 in main /scdoc/src/main.c:763:2
3 0x7f99252ab0b2 in __libc_start_main
/build/glibc-YYA7BZ/glibc-2.31/csu/../csu/libc-start.c:308:16
4 0x41b3fd in _start (/scdoc/scdoc+0x41b3fd)
В исходниках на данной строчке написано вот что:
if (!isalnum(last) || ((p->flags & FORMAT_UNDERLINE) && !isalnum(next))) {
Подсказка: p
— это корректный, ненулевой указатель. Переменные last
и next
имеют тип uint32_t
. Сегфолт случается на втором вызове функции isalnum
. И, самое важное: воспроизводится только при использовании glibc, но не musl libc. Если вам пришлось перечитать код несколько раз, вы не одиноки: тут попросту нечему вызывать сегфолт.
Поскольку было известно, что все дело в библиотеке glibc, я достал ее исходники и стал искать реализацию isalnum
, готовясь столкнуться с какой-нибудь дурацкой фигней. Но прежде чем я дойду до дурацкой фигни, которой там, уж поверьте, навалом, давайте сначала быстренько поглядим на хороший вариант. Вот так функция isalnum
реализована в musl libc:
int isalnum(int c)
{
return isalpha(c) || isdigit(c);
}
int isalpha(int c)
{
return ((unsigned)c|32)-'a' < 26;
}
int isdigit(int c)
{
return (unsigned)c-'0' < 10;
}
Как и ожидалось, для любого значения c
функция отработает без сегфолта, потому что с какого хрена вообще isalnum
должна кидать сегфолт?
Ладно, теперь сравним это с реализацией glibc. Как только вы откроете заголовок, вас будет встречать типичная GNU’шная галиматья, но пропустим ее и попытаемся найти isalnum
.
Первый результат такой:
enum
{
_ISupper = _ISbit (0), /* UPPERCASE. */
_ISlower = _ISbit (1), /* lowercase. */
// ...
_ISalnum = _ISbit (11) /* Alphanumeric. */
};
Похоже на деталь реализации, двигаемся дальше.
__exctype (isalnum);
Но что такое __exctype
? Возвращаемся на несколько строчек вверх…
#define __exctype(name) extern int name (int) __THROW
Ладно, по всей видимости это только прототип. Непонятно правда, зачем тут нужен макрос. Ищем дальше…
#if !defined __NO_CTYPE
# ifdef __isctype_f
__isctype_f (alnum)
// ...
Так, вот это уже похоже на что-то полезное. Что такое __isctype_f
? Мотаем вверх…
#ifndef __cplusplus
# define __isctype(c, type)
((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
#elif defined __USE_EXTERN_INLINES
# define __isctype_f(type)
__extern_inline int
is##type (int __c) __THROW
{
return (*__ctype_b_loc ())[(int) (__c)] & (unsigned short int) _IS##type;
}
#endif
Ну начинается… Ладно, вместе как-нибудь разберемся. Видимо, __isctype_f
— это инлайн-функция… стоп, это все находится внутри блока else препроцессорной инструкции #ifndef __cplusplus. Тупик. Где же isalnum
, мать ее, на самом деле определена? Ищем дальше… Может вот оно?
#if !defined __NO_CTYPE
# ifdef __isctype_f
__isctype_f (alnum)
// ...
# elif defined __isctype
# define isalnum(c) __isctype((c), _ISalnum) // <- вот тут
Эй, это же «деталь реализации», которую мы видели раньше. Помните?
enum
{
_ISupper = _ISbit (0), /* UPPERCASE. */
_ISlower = _ISbit (1), /* lowercase. */
// ...
_ISalnum = _ISbit (11) /* Alphanumeric. */
};
Попробуем по-быстрому расковырять этот макрос:
# include <bits/endian.h>
# if __BYTE_ORDER == __BIG_ENDIAN
# define _ISbit(bit) (1 << (bit))
# else /* __BYTE_ORDER == __LITTLE_ENDIAN */
# define _ISbit(bit) ((bit) < 8 ? ((1 << (bit)) << 8) : ((1 << (bit)) >> 8))
# endif
Ну что за фигня? Ладно, двигаем дальше и считаем, что это просто магическая константа. Другой макрос называется __isctype
, который похож на недавно виденный нами __isctype_f
. Посмотрим еще разок на ветку #ifndef __cplusplus
:
#ifndef __cplusplus
# define __isctype(c, type)
((*__ctype_b_loc ())[(int) (c)] & (unsigned short int) type)
#elif defined __USE_EXTERN_INLINES
// ...
#endif
Эээ…
Ну, по крайней мере мы нашли разыменовывание указателя, которое могло бы объяснить сегфолт. А что такое __ctype_b_loc
?
/* Эти объявления находятся в файле ctype-info.c.
Они должны совпадать с объявлениями в файле localeinfo.h.
В модели локалей, основывающейся на потоках, (см. `uselocale' в <locale.h>)
мы не можем пользоваться глобальными переменными, как раньше.
Вместо этого, ниже указаны функции-аксессоры, которые возвращают адрес
каждой переменной, относящейся к текущему потоку, если потоков несколько.
Они указывают на массивы из 384 элементов, поэтому для индексации можно
использовать значение `unsigned char' [0,255]; а также EOF (-1); или любое
значение `signed char' value [-128,-1). ISO C требует, чтобы функции ctype работали
со значениями типа `unsigned char' и EOF; мы также поддерживаем отрицательные
значения `signed char' для совместимости со старыми некорректными программами.
Массивы для конвертации регистра содержат значения типа `int`,
а не `unsigned char`, потому что `tolower(EOF)' должно возвращать EOF, а это значение
не помещается в диапазон `unsigned char`. Однако сейчас самое важное - то, что
эти массивы также используются для многобайтовых кодировок. */
extern const unsigned short int **__ctype_b_loc (void)
__THROW __attribute__ ((__const__));
extern const __int32_t **__ctype_tolower_loc (void)
__THROW __attribute__ ((__const__));
extern const __int32_t **__ctype_toupper_loc (void)
__THROW __attribute__ ((__const__));
Как круто с твоей стороны, glibc! Я просто обожаю иметь дело с локалями. Так или иначе, к моему упавшему приложению подключен gdb, и держа в уме всю полученную информацию я пишу вот это убожество:
(gdb) print ((unsigned int **(*)(void))__ctype_b_loc)()[next]
Cannot access memory at address 0x11dfa68
Сегфолт найден. В комменте была про это строчка: «ISO C требует, чтобы функции ctype работали со значениями типа `unsigned char’ и EOF». Если найти это в спецификации, увидим:
Во всех реализациях [функций, объявленных в ctype.h], аргументом является int, значение которого должно помещаться в unsigned char, или же равняться значению макроса EOF.
Теперь становится очевидно, как исправить проблему. Мой косяк. Оказывается, я не могу скормить в isalnum
произвольный символ UCS-32 для проверки на его вхождение в диапазоны 0x30-0x39, 0x41-0x5A и 0x61-0x7A.
Но тут я возьму на себя смелость предположить: а может быть, функция isalnum
вообще не должна кидать сегфолт, вне зависимости от того, что ей передадут? Может быть, даже если спецификация это разрешает, это не означает, что так надо делать? Может быть, ну просто в качестве безумной идеи, поведение этой функции не должно содержать пять макросов, проверять использование компилятора C++, зависеть от порядка байтов вашей архитектуры, таблицы поиска, данных о локали потока и разыменовывать два указателя?
Еще разок посмотрим на версию в musl в качестве быстрого напоминания:
int isalnum(int c)
{
return isalpha(c) || isdigit(c);
}
int isalpha(int c)
{
return ((unsigned)c|32)-'a' < 26;
}
int isdigit(int c)
{
return (unsigned)c-'0' < 10;
}
Вот такие пироги.
Примечание переводчика: спасибо MaxGraey за ссылку на оригинал.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Ваше мнение
42.67%
Автор прав: в glibc перемудрили
198
27.37%
Автор неправ: стандарт есть стандарт
127
29.96%
Мне все равно — как хорошо, что я не пишу на си
139
Проголосовали 464 пользователя.
Воздержались 75 пользователей.
bool isctype( CharT c, char_class_type f ) const; |
Determines whether the character c
belongs to the character class identified by f
, which, in turn, is a value returned by lookup_classname()
or a bitwise OR of several such values.
The version of this function provided in the standard library specializations of std::regex_traits
does the following:
1) First converts f
to some temporary value m
of type std::ctype_base::mask
in implementation-defined manner
2) Then attempts to classify the character in the imbued locale by calling std::use_facet<std::ctype<CharT>>(getloc()).is(m, c)
. If that returned true
, true
is returned by isctype()
.
3) Otherwise, checks whether c
equals '_'
and the bitmask f
includes the result of calling lookup_classname()
for the character class [:w:]
, in which case true
is returned.
4) Otherwise, false
is returned.
Parameters
c | — | the character to classify |
f | — | the bitmask obtained from one or several calls to lookup_classname() |
Return value
true
if c
is classified by f
, false
otherwise.
Notes
The description above summarizes C++14; the C++11 phrasing required this function to return true for '_'
in all cases (LWG issue 2018).
Example
#include <iostream> #include <string> #include <regex> int main() { std::regex_traits<char> t; std::string str_alnum = "alnum"; auto a = t.lookup_classname(str_alnum.begin(), str_alnum.end()); std::string str_w = "w"; // [:w:] is [:alnum:] plus '_' auto w = t.lookup_classname(str_w.begin(), str_w.end()); std::cout << std::boolalpha << t.isctype('A', w) << ' ' << t.isctype('A', a) << 'n' << t.isctype('_', w) << ' ' << t.isctype('_', a) << 'n' << t.isctype(' ', w) << ' ' << t.isctype(' ', a) << 'n'; }
Output:
true true true false false false
demonstraits a custom regex_traits implementation of lookup_classname/isctype.
#include <iostream> #include <locale> #include <regex> #include <cwctype> // This custom regex traits uses wctype/iswctype to implement lookup_classname/isctype struct wctype_traits : std::regex_traits<wchar_t> { using char_class_type = std::wctype_t; template<class It> char_class_type lookup_classname(It first, It last, bool=false) const { return std::wctype(std::string(first, last).c_str()); } bool isctype(wchar_t c, char_class_type f) const { return std::iswctype(c, f); } }; int main() { std::locale::global(std::locale("ja_JP.utf8")); std::wcout.sync_with_stdio(false); std::wcout.imbue(std::locale()); std::wsmatch m; std::wstring in = L"風の谷のナウシカ"; // matches all characters (they are classified as alnum) std::regex_search(in, m, std::wregex(L"([[:alnum:]]+)")); std::wcout << "alnums: " << m[1] << 'n'; // prints "風の谷のナウシカ" // matches only the katakana std::regex_search(in, m, std::basic_regex<wchar_t, wctype_traits>(L"([[:jkata:]]+)")); std::wcout << "katakana: " << m[1] << 'n'; // prints "ナウシカ" }
Output:
alnums: 風の谷のナウシカ katakana: ナウシカ
See also
gets a character class by name (public member function) |
|
[virtual] |
classifies a character or a character sequence (virtual protected member function of std::ctype<CharT> ) |
classifies a wide character according to the specified LC_CTYPE category (function) |
description | title | ms.date | api_name | api_location | api_type | topic_type | f1_keywords | helpviewer_keywords | ms.assetid | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Learn more about: _isctype, iswctype, _isctype_l, _iswctype_l |
_isctype, iswctype, _isctype_l, _iswctype_l |
4/2/2020 |
|
|
DLLExport |
apiref |
|
|
cf7509b7-12fc-4d95-8140-ad2eb98173d3 |
_isctype
, iswctype
, _isctype_l
, _iswctype_l
Tests c
for the ctype
property specified by the desc
argument. For each valid value of desc
, there’s an equivalent wide-character classification routine.
Syntax
int _isctype( int c, _ctype_t desc ); int _isctype_l( int c, _ctype_t desc, _locale_t locale ); int iswctype( wint_t c, wctype_t desc ); int _iswctype_l( wint_t c, wctype_t desc, _locale_t locale );
Parameters
c
Integer to test.
desc
Property to test for. The property is normally retrieved using ctype
or wctype
.
locale
The locale to use for any locale-dependent tests.
Return value
_isctype
and iswctype
return a nonzero value if c
has the property specified by desc
in the current locale. Otherwise, they return 0. The versions of these functions with the _l
suffix are identical except that they use the locale passed in instead of the current locale for their locale-dependent behavior. For more information, see Locale.
The behavior of _isctype
and _isctype_l
is undefined if c
isn’t EOF or in the range 0 through 0xFF, inclusive. When a debug CRT library is used and c
isn’t one of these values, the functions raise an assertion.
Generic-text routine mappings
Tchar.h routine | _UNICODE and _MBCS not defined |
_MBCS defined |
_UNICODE defined |
---|---|---|---|
n/a | _isctype |
n/a | _iswctype |
n/a | _isctype_l |
n/a | _iswctype_l |
Remarks
By default, this function’s global state is scoped to the application. To change this behavior, see Global state in the CRT.
Requirements
Routine | Required header |
---|---|
_isctype |
<ctype.h> |
iswctype |
<ctype.h> or <wchar.h> |
_isctype_l |
<ctype.h> |
_iswctype_l |
<ctype.h> or <wchar.h> |
For more compatibility information, see Compatibility.
Libraries
All versions of the C run-time libraries.
See also
Character classification
Locale
is
, isw
routines
- Forum
- General Programming Boards
- C Programming
- Assertion Failure
Thread: Assertion Failure
-
07-21-2006
#1
Registered User
I’m using Microsoft Visual Studio 2005 for Windows XP.
I have my program compiling, but when I run it I get 2 errors from the
Microsoft Visual C++ Dbug Library in the microsoft file isctype.c. Both errors are the same — Expression: (unsigned)(c + 1) <= 256. The errors occur on the following lines where _ASSERTE occurs in isctype.c:Code:
#if defined (_DEBUG) extern "C" int __cdecl _chvalidator( int c, int mask ) { _ASSERTE((unsigned)(c + 1) <= 256); return _chvalidator_l(NULL, c, mask); } extern "C" int __cdecl _chvalidator_l( _locale_t plocinfo, int c, int mask ) { _LocaleUpdate _loc_update(plocinfo); _ASSERTE((unsigned)(c + 1) <= 256); if (c >= -1 && c <= 255) { return (_loc_update.GetLocaleT()->locinfo->pctype[c] & mask); } else { return (_loc_update.GetLocaleT()->locinfo->pctype[-1] & mask); } }
-
07-21-2006
#2
Code Goddess
Please post the code you wrote that causes this error.
My best code is written with the delete key.
-
07-21-2006
#3
and the hat of int overfl
My guess is you did some ctype test on EOF.
-
07-21-2006
#4
Registered User
Thanks for getting back to me. Here is the code that’s causing the error:
Code:
#include <stdio.h> #include <conio.h> #include "molecule.h" #include "smiles.h" #include "smierr.h" main( int argc, char *argv[] ) { char buf[200]; char s[MAX_SMI]; char sf[MAX_SMI]; int Error, ErCode; int N_Frag, Found; MOLECULE m; RINGS r; long id; FILE *ff, *fs, *fo; if ( argc != 4 ) { printf( "USAGE: fragment <smiles-file> <fragment-file> <output-file>n" ); exit( 1 ); } if ( (fs = fopen( argv[1], "r" )) == NULL ) { printf( "Unable to open SMILES file %sn", argv[1] ); exit( 1 ); } if ( (ff = fopen( argv[2], "r" )) == NULL ) { printf( "Unable to open FRAGMENT file %sn", argv[2] ); exit( 1 ); } if ( (fo = fopen( argv[3], "w" )) == NULL ) { printf( "Unable to open OUTPUT file %sn", argv[3] ); exit( 1 ); } printf( " Processed: " ); fgets( buf, 200, fs ); /* Retrieve line from smiles file */ sscanf( buf, "%ld %s", &id, s); while ( !feof( fs ) ) { if ( (Error = InSmi( s, &m, &ErCode, 0 )) != 0 ) { printf( "SMILES ERROR for %ld", id ); getch(); } else if ( (Error = ChkVal( &m )) != 0 ) { printf("VALENCE ERROR for %ld", id ); getch(); } else { FindRings(&m,&r); Found = 0; fscanf( ff, "%s", sf ); while ( (!feof( ff )) && !Found ) { N_Frag = EV_Num( sf, &m, &r ); if ( N_Frag > 0 ) { fprintf( fo, "%10ld|%sn", id, s ); Found = 1; } else if ( N_Frag < 0 ) { printf( "FRAGMENT ERRORn" ); exit( 1 ); } fscanf( ff, "%s", sf ); } rewind( ff ); } printf( "Processing %7ldn", id ); fgets( buf, 200, fs ); /* Retrieve line from smiles file */ sscanf( buf, "%ld %s", &id, s); } fclose( fs ); fclose( ff ); fclose( fo ); exit( 0 ); }
-
07-21-2006
#5
and the hat of int overfl
But that’s not all the code.
1. Compile it all with debug.
2. Run the code in the debugger.
3. When you get an assert, drop into the debugger and get a stack trace.
4. Follow the stack backwards until you get into your code.
5. Explore around there to work out why you’re passing an out of range value.Also, read the FAQ on why feof() is bad in control loops.
-
07-21-2006
#6
Registered User
Thanks Salem, that gets me going in the right direction.
Popular pages
- Exactly how to get started with C++ (or C) today
- C Tutorial
- C++ Tutorial
- 5 ways you can learn to program faster
- The 5 Most Common Problems New Programmers Face
- How to set up a compiler
- 8 Common programming Mistakes
- What is C++11?
- Creating a game, from start to finish
Recent additions
- How to create a shared library on Linux with GCC — December 30, 2011
- Enum classes and nullptr in C++11 — November 27, 2011
- Learn about The Hash Table — November 20, 2011
- Rvalue References and Move Semantics in C++11 — November 13, 2011
- C and C++ for Java Programmers — November 5, 2011
- A Gentle Introduction to C++ IO Streams — October 10, 2011
Similar Threads
-
Replies: 5
Last Post: 12-25-2008, 04:47 AM
-
Replies: 8
Last Post: 01-21-2008, 02:22 AM
-
Replies: 2
Last Post: 07-20-2004, 11:23 AM
-
Replies: 0
Last Post: 02-10-2003, 08:18 PM
-
Replies: 9
Last Post: 01-04-2003, 07:02 PM
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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
// Части речи.cpp: определяет точку входа для консольного приложения. // #include "stdafx.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h>//для isspace #define MAXWORD 25 #define BUFFER 100 char *PerfectiveGerund[]={ "12", "ав","яв","авши","явши","авшись","явшись","ив","ивши","ившись","ыв","ывши","ывшись" }; char *adjectivalend[]={ "26", "ее", "ие", "ые","ое","ими","ыми","ей","ий","ый","ой","ем","им","ым", "ом","его","ого","ему","ому","их","ых","ую","юю","ая","яя","ою","ею" }; char *participlesuf[]={ "12", "ущ","ющ","ащ","ящ","вш","ш","ем","ом","им","нн","енн","т" }; char *shortparticipleend[]={ "3", "ы","а","о" }; char *shortparticiplesuf[]={//Качан будет причастием "3", "ан","ян","ен" }; char *superlativesuf[]={ "2", "ейш","ейше" }; typedef struct tnode{ char *word; int count; struct tnode *left; struct tnode *right; } Treenode; int index; //26 okon4anii char *getword(FILE *); Treenode *addtree(Treenode *,char *); void treeprint (Treenode *,Treenode **wordsList); char *wordMemory(char *); FILE *openFile(char *,char *); int Mystrstr(char *,char *);//это для обрезки по заданному " " int stem(char *, char *part[]);//это для обрезки из массива концов слов. Можно сделать перезагрузку методов но хз как int cons(char *); int vowel(char *); int _tmain(int argc, _TCHAR* argv[]) { Treenode *root; char *word; char *pch; FILE *fin=openFile("input.txt","r"); int participlecount=0; root=NULL; while ((word=getword(fin))){ printf("ljsldfjkn"); printf("%sn",word); if (strlen(word)<=3){//sly4ai vs9kix + - , predlogov iz 1 bykvi continue; } ////////////////////////////////////// //do vsex preobrazovanii videl9t 4ast slova s 1 glasnooi. Rv po algoritmy //strtok(word,".,!?:;"");//Реализовано в getword.otdelenie ot slov znakov sto9shix vplotnyu. В начале стоять не могут в силу ф-ции getword. pch=new char[strlen(word)]; strcpy(pch,word);//Тут потому что надо отделить знаки. Уже неважно. Можно и в начале while if (strpbrk(word,"0123456789-")==NULL){//Проверка не число ли это или прил. Пример, 9-тикратный continue;//esli v slove defis to eto ili syshestvitelnoe ili prilagatelnoe } if (stem(word,PerfectiveGerund)){//Тогда это деепричастие continue; } if (Mystrstr(word,"ся")){//ся+прил окончание => причастие. Не пройдут "пейся, лейся и т.д.". Просто ся не подходит if (stem(word,adjectivalend)){ root=addtree(root,pch); ++participlecount;//Можно засунуть глобальную переменную в addtree ф-цию, а можно оставить } continue; } if (Mystrstr(word,"ть")){//глагол continue; } if (vowel(word)<2){//Число гласных во всех причастиях >=2 continue; } if (stem(word,adjectivalend)){ /*if (stem(word,superlativesuf)){//Прилагательное в превосходной форме }*/ if (stem(word,participlesuf)){//polnie pri4asti9 root=addtree(root,pch); ++participlecount;//нашли } continue; } if (Mystrstr(word,"т")){//Могут быть и краткие причастия мужского рода а также существительные- автомат,малахит и др. Поэтому откидываем. А в след if уже проверка без этого неугодного суффикса "т" continue; } if (stem(word,shortparticiplesuf)){//краткие причастия мужского рода (без окончания)//Качан будет причастием, root=addtree(root,pch); ++participlecount;//нашли continue;; } if (stem(word,shortparticipleend)&&stem(word,shortparticiplesuf)){//kratkie pri4asti9 ++participlecount;//нашли root=addtree(root,pch); continue; } printf("lkjsldfj"); printf ("%s",pch); delete[] word; delete[] pch; } /*printf("%d",participlecount); Не нужно. Буду считать вне функции*/ Treenode **wordsList=new Treenode*[participlecount]; index=0;//Глобальный счётчик для рекурсии в treeprint treeprint(root, wordsList); char c; scanf("%c",&c); return 0; } void treeprint (Treenode *p, Treenode **wordsList){ if (p!=NULL){ treeprint (p->left, wordsList); wordsList[index++]=p;// берём адрес для массива указателей printf("%4d %sn",p->count,p->word); treeprint (p->right,wordsList); } } char *getword(FILE *fin){//0-ошибка в потоке ввода, остальное - ок. Считывает слово из потока. Fscanf не подходит т.к. мы определяем max размер слова. А fscanf в случае слова большего размера чем MAXWORD выдаст ошибку неотличимую от конца файла и т.д. char c; //int getc(FILE *);//Надо объявлять? char *w=new char[BUFFER]; while (!isalnum(c=getc(fin))){ if (c==EOF){ return NULL; } } w[0]=c; int i=1; while ( isalnum(c=getc(fin)) || (c=='-')){//c=='-' можно убрать. w[i++]=c; //printf("%d %sn",i-1,w[i-1]); if (i>=BUFFER){ w=(char*)realloc(w,BUFFER*sizeof(char)); } } return w; } /*int *getword(FILE *fin, char *word, int lim){//0-ошибка в потоке ввода, остальное - ок. Считывает слово из потока. Fscanf не подходит т.к. мы определяем max размер слова. А fscanf в случае слова большего размера чем MAXWORD выдаст ошибку неотличимую от конца файла и т.д. int c; //printf ("%c",c); if (isalnum(c)){//Проверка на первую букву слова. -?, не могут стоять в начале слова. Но может 5-тидневный. Это для нас нормально *w++=c; } else if (c==EOF){ return EOF; } else if ({ return 0; } for ( ;--lim>0;++w){ if (isspace(*w=getc(fin))){ break; } //printf ("%c",*w); } *w=''; //printf ("%s",word); return word[0]; }*/ /*int *getword(FILE *fin, char *word, int lim){//0-ошибка в потоке ввода, остальное - ок. Считывает слово из потока. Fscanf не подходит т.к. мы определяем max размер слова. А fscanf в случае слова большего размера чем MAXWORD выдаст ошибку неотличимую от конца файла и т.д. int c; //int getc(FILE *);//Надо объявлять? char *w=word; while (isspace(c=getc(fin))) ; //printf ("%c",c); if (isalnum(c)){//Проверка на первую букву слова. -?, не могут стоять в начале слова. Но может 5-тидневный. Это для нас нормально *w++=c; } else if (c==EOF){ return EOF; } else if ({ return 0; } for ( ;--lim>0;++w){ if (isspace(*w=getc(fin))){ break; } //printf ("%c",*w); } *w=''; //printf ("%s",word); return word[0]; }*/ char *wordMemory(char *s){//Выделени памяти под слово. strlen char *p; p=new char[strlen(s)+1]; /*+1 для '' */ if (p!=NULL){ strcpy(p,s); } return p; } Treenode *addtree(Treenode *p,char *w){ int cond; if (p==NULL){ p=new Treenode; p->word=wordMemory(w); p->count=1; p->left=p->right=NULL; } else if ((cond=strcmp(w,p->word))== 0){ p->count++; } else if (cond<0){ p->left=addtree(p->left,w); } else{ p->right=addtree(p->right,w); } return p; } FILE *openFile(char *filename,char *mode){//в fopen сделано через указатели.filename-имя создаваемого файла,mode - тип открытия файла- wb и т.д. FILE *f=fopen(filename,mode); if (f==NULL){ perror("Error opening file"); getchar(); exit (-1); } return f; } int Mystrstr(char *pch,char *needle){//1, если needle входит в слово с конца, 0 - иначе int L,k; L=strlen(pch); k=strlen(needle); if (L<k){ return 0; } while (k>0){ if (pch[L-1]!=needle[k-1]){ return 0; } L--; k--; } pch[L]=''; return 1; } int stem(char *pch, char *part[]){//1 esli nashel vxojdeni9. 0- ina4e. int n=atoi(part[0]);//длина массива окончаний/суффиксов for (int i=1;i<=n;++i){//<=n т.к. массивы с частями на 1 больше чем n, а нужные значения начинаются с идекса 1 if (Mystrstr(pch,part[i])){//slovo soderjit part[i](okon4anie/suffix) v konce return 1; } } return 0; } int cons(char *p){//proverka glasna9 li bykva switch (*p){ case 'а': case 'о': case 'у': case 'ы': case 'и': case 'э': case 'я': case 'ё': case 'ю': case 'е': return 1; default: return 0; } } int vowel(char *p){//return 4islo glasnix int L=strlen(p); int nvowel=0; for (int i=0;i<L;++i,++p){ if (cons(p)){ ++nvowel; } } return nvowel;//mojet bit odno im9 y peremennoi i fynkcii v kotoroi ona naxodits9?esli da to nazvat fynkciu nvowel } |
I’ve been trying to use cv::VideoCapture::open(«< path to video file >») in QtCreator (opencv added). Even though the program runs without errors in «bebug mode» (debug build), it gives below runtime error in «release mode» (release build).
Debug Assertion Failed File:
f:/dd/vctools/crt_bld/self_x86/src/isctype.c Line: 56 Expression:
(unsigned)(c+1) <= 256
It is a simple program which uses only cv::VideoCapture::open() [for testing purposes]
Below is the .pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:/C/opencv/build/include
INCLUDEPATH += C:/C/opencv/build/include/opencv
LIBS += C:/C/opencv/build/x86/vc10/lib/opencv_highgui240d.lib
LIBS += C:/C/opencv/build/x86/vc10/lib/opencv_highgui240.lib
LIBS += C:/C/opencv/build/x86/vc10/bin/opencv_highgui240d.dll
LIBS += C:/C/opencv/build/x86/vc10/bin/opencv_highgui240.dll
Below is the Header file
#include <QMainWindow>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
cv::VideoCapture vcap;
};
Below is the .cpp file
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
vcap.open("C:/Users/ANURUDDHA/pedestrians/ThreePastShop2cor.mpg");
}
MainWindow::~MainWindow()
{
delete ui;
}
When I pass an int
as the argument to cv::VideoCapture::open() [eg: vcap.open(0)] it runs without errors in both debug and release build and opens webcam successfully. Problem comes only when I pass a String to arguments.
Someone please shed some light on this. Really appreciated.
I’ve been trying to use cv::VideoCapture::open(«< path to video file >») in QtCreator (opencv added). Even though the program runs without errors in «bebug mode» (debug build), it gives below runtime error in «release mode» (release build).
Debug Assertion Failed File:
f:/dd/vctools/crt_bld/self_x86/src/isctype.c Line: 56 Expression:
(unsigned)(c+1) <= 256
It is a simple program which uses only cv::VideoCapture::open() [for testing purposes]
Below is the .pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled
TEMPLATE = app
SOURCES += main.cpp
mainwindow.cpp
HEADERS += mainwindow.h
FORMS += mainwindow.ui
INCLUDEPATH += C:/C/opencv/build/include
INCLUDEPATH += C:/C/opencv/build/include/opencv
LIBS += C:/C/opencv/build/x86/vc10/lib/opencv_highgui240d.lib
LIBS += C:/C/opencv/build/x86/vc10/lib/opencv_highgui240.lib
LIBS += C:/C/opencv/build/x86/vc10/bin/opencv_highgui240d.dll
LIBS += C:/C/opencv/build/x86/vc10/bin/opencv_highgui240.dll
Below is the Header file
#include <QMainWindow>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
cv::VideoCapture vcap;
};
Below is the .cpp file
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
vcap.open("C:/Users/ANURUDDHA/pedestrians/ThreePastShop2cor.mpg");
}
MainWindow::~MainWindow()
{
delete ui;
}
When I pass an int
as the argument to cv::VideoCapture::open() [eg: vcap.open(0)] it runs without errors in both debug and release build and opens webcam successfully. Problem comes only when I pass a String to arguments.
Someone please shed some light on this. Really appreciated.