Я думаю, я бы сделал эту работу немного по-другому, рассматривая std::string
как коллекцию и используя алгоритм.При использовании лямбды C ++ 0x это будет выглядеть примерно так:
bool has_special_char(std::string const &str) {
return std::find_if(str.begin(), str.end(),
[](char ch) { return !(isalnum(ch) || ch == '_'); }) != str.end();
}
По крайней мере, когда вы имеете дело с char
(не wchar_t
), isalnum
обычно будет использовать таблицупосмотрите, так что обычно (немного) быстрее, чем что-либо, основанное на find_first_of
(вместо этого обычно используется линейный поиск).Итак, это O (N) (N = str.size ()), где что-то, основанное на find_first_of
, будет O (N * M), (N = str.size (), M = pattern.size ()).
Если вы хотите выполнить работу с чистым C, вы можете использовать scanf
с преобразованием набора сканирования, которое теоретически непереносимо, но поддерживается практически всеми недавними / популярными компиляторами:
char junk;
if (sscanf(str, "%*[A-Za-z0-9_]%c", &junk))
/* it has at least one "special" character
else
/* no special characters */
Основная идея здесь довольно проста: скансет пропускает все последовательные не специальные символы (но не присваивает результат чему-либо из-за *
), затем мы пытаемся прочитать еще один символ.Если это удается, это означает, что был по крайней мере один символ, который был не пропущен, поэтому мы должны иметь по крайней мере один специальный символ.Если это не удается, это означает, что преобразование набора сканирования соответствует всей строке, поэтому все символы были «не специальными».
Официально стандарт C говорит, что попытка поместить диапазон в преобразование набора сканирования, как это't portable (a' - 'в любом месте, кроме начала или конца набора сканирования, дает поведение, определяемое реализацией).Было даже несколько компиляторов (из Borland), которые потерпели бы неудачу из-за этого - они рассматривали бы A-Z
как совпадающие ровно с тремя возможными символами, «A», «-» и «Z».Большинство современных компиляторов (или, точнее, реализации стандартной библиотеки) используют подход, который предполагает: «AZ» соответствует любому символу верхнего регистра.