Поэтому я сейчас пишу часть программы, которая принимает пользовательский текст. Я хочу игнорировать все входные символы, которые не являются алфавитными, и поэтому я подумал, что std :: isalpha () будет хорошим способом сделать это. К сожалению, насколько я знаю, есть две функции std :: isalpha (), и общую функцию необходимо отстранить от специфичной для локали:
(int(*)(int))std::isalpha()
Если я не устраню неоднозначность, std :: isalpha, похоже, возвращает true при чтении заглавных букв, но false при чтении строчных букв (хотя, если я непосредственно печатаю возвращаемое значение, он возвращает 0 для не-буквенных символов, 1 для символов верхнего регистра и 2 для строчных букв). Так что мне нужно сделать это.
Я делал это раньше в другой программе, но по какой-то причине в этом проекте я иногда получаю ошибки «ISO C ++ запрещает». Обратите внимание, только иногда. Вот проблемная область кода (она появляется вместе без чего-либо промежуточного):
std::cout << "Is alpha? " << (int(*)(int))std::isalpha((char)Event.text.unicode) << "\n";
if ( (int(*)(int))std::isalpha((char)Event.text.unicode) == true)
{
std::cout << "Is alpha!\n";
//...snip...
}
Первый экземпляр, куда я отправляю возвращенное значение в std :: cout, работает нормально — я не получаю ошибок для этого, я получаю ожидаемые значения (0 для не альфа, 1 для альфа), и если это единственное место, где я попробуйте устранить неоднозначность, программа компилируется и работает нормально.
Второй экземпляр, однако, выбрасывает это:
error: ISO C++ forbids comparison between pointer and integer
и компилируется, только если я удаляю фрагмент (int (*) (int)), после чего возникает плохое поведение. Может ли кто-нибудь просветить меня здесь?
Вы кастуете возвращаемое значение из std::alpha()
позвонить int(*)(int)
, а затем сравнить этот указатель с true
, Сравнение указателей с логическими значениями не имеет большого смысла, и вы получите ошибку.
Теперь, без актерского состава, вы сравниваете int
вернулся std::alpha()
в true
, bool
является целочисленным типом, и для сравнения двух различных целочисленных типов значения сначала преобразуются в один и тот же тип. В этом случае они оба преобразуются в int
, true
становится 1
, и если std::isalpha()
возвращенный 2
сравнение заканчивается 2 != 1
,
Если вы хотите сравнить результат std::alpha()
против bool
Вы должны разыграть что вернулось в bool
или просто пропустите сравнение и используйте что-то вроде if (std::isalpha(c)) {...}
Нет необходимости устранять неоднозначность, потому что в обычном вызове нет двусмысленности.
Кроме того, нет необходимости использовать std::
префикс, когда вы получаете объявление функции от <ctype.h>
, который после C ++ 11 является заголовком, который вы должны предпочтительно использовать (т.е. не <cctype>
) — и в этом отношении также до C ++ 11, но C ++ 11 закрепил это.
В-третьих, вы не должны сравнивать результат с true
,
Тем не менее, вы должны бросить char
аргумент unsigned char
Чтобы вы не получили неопределенного поведения для всего, кроме 7-битного ASCII.
Например. делай так:
bool isAlpha( char const c )
{
typedef unsigned char UChar;
return !!isalpha( UChar( c ) );
}