std::string
をコレクションとして扱い、アルゴリズムを使用して、少し違った方法で仕事をすると思います。C++0x ラムダを使用すると、次のようになります。
bool has_special_char(std::string const &str) {
return std::find_if(str.begin(), str.end(),
[](unsigned char ch) { return !(isalnum(ch) || ch == '_'); }) != str.end();
}
char
少なくとも(not wchar_t
)を扱っているときは、通常はテーブル ルックアップを使用するため、(通常は代わりに線形検索を使用する) にisalnum
基づくものよりも (かなり) 高速になります。find_first_of
IOW、これは O(N) (N=str.size()) であり、これに基づくものfind_first_of
は O(N*M)、(N=str.size()、M=pattern.size()) になります。
純粋な C でジョブを実行する場合は、scanf
理論的には移植性がありませんが、基本的にすべての最近の/人気のあるコンパイラでサポートされている scanset 変換を使用できます。
char junk;
if (sscanf(str, "%*[A-Za-z0-9_]%c", &junk))
/* it has at least one "special" character
else
/* no special characters */
ここでの基本的な考え方は非常に単純です: scanset は連続するすべての非特殊文字をスキップし (ただし、*
. それが成功した場合、スキップされなかった文字が少なくとも 1 つあったことを意味するため、少なくとも 1 つの特殊文字が必要です。失敗した場合は、scanset 変換が文字列全体に一致したため、すべての文字が「非特殊」だったことを意味します。
公式には、C 標準では、このようにスキャンセット変換に範囲を入れようとすると移植性がないとされています (スキャンセットの先頭または末尾以外の場所に '-' を付けると、実装で定義された動作が得られます)。これに失敗する (Borland の) コンパイラもいくつかありました。これらのコンパイラはA-Z
、'A'、'-'、'Z' の 3 つの文字に正確に一致するものとして扱います。現在のほとんどのコンパイラ (または、より正確には、標準ライブラリの実装) は、これが想定するアプローチを採用しています。「AZ」は、任意の大文字に一致します。