2011-09-30 5 views
14

내가 AZ 문자와 같은 유효한 문자에 대한 문자열 ...

string name; 

cout << "Enter your name" 
cin >> name; 

string letters = "qwertyuiopasdfghjklzxcvbnm"; 

string::iterator it; 

for(it = name.begin(); it = name.end(); it++) 
{ 
    size_t found = letters.find(it); 
} 
+4

숙제 인 경우 ... 표시해야합니다. –

+0

무엇이 당신의 질문입니까? 코드가 잘못 되었습니까? 아니면 누락 된 코드입니까? 어떤 경우에, 무엇? –

+3

'* it'. btw 또한 dvorak 레이아웃으로 시도해보십시오. –

답변

3

STL 방식으로 테스트 할 수있는 방법을 문자에 대한 문자열 테스트 방법 :

struct TestFunctor 
{ 
    bool stringIsCorrect; 
    TestFunctor() 
    :stringIsCorrect(true) 
    {} 

    void operator() (char ch) 
    { 
    if(stringIsCorrect && !((ch <= 'z' && ch >= 'a') || (ch <= 'Z' && ch >= 'A'))) 
     stringIsCorrect = false; 
    } 
} 

TestFunctor functor; 

for_each(name.begin(), name.end(), functor); 

if(functor.stringIsCorrect) 
    cout << "Yay"; 
+0

테스트 매개 변수의 일부로 공백을 포함하고 싶다면 어떨까요? 어떻게 할거 니? – miatech

+0

if (stringIsCorrect &&! (ch <= 'z'&& ch> = 'a') || (ch <= 'Z'&& ch> = 'A')))' (ch == ''))) ' – GreenScape

+1

인코딩은 다음과 같은 것을 유의하십시오. ((ch <='z '&& ch> ='a ') || (ch <='Z '&& ch> ='A ' [EBCDIC] (https://en.wikipedia.org/wiki/EBCDIC)에는 문자가 아닌''a ''와 ''z ''사이에 문자가 있습니다. – Jarod42

43

먼저, std::cin >> name 의지를 사용하여 >>이 공백 문자로 입력을 나누기 때문에 사용자가 John Smith을 입력하면 실패합니다. 당신은 이름을 가져 std::getline()를 사용해야합니다 문자열은 알파벳 문자가 포함되어 있는지 확인하는 방법은 많습니다

다음
std::getline(std::cin, name); 

우리가 갈 ...

. 그러나 빠른 속도로 복잡하게

bool contains_non_alpha 
    = name.find_first_not_of("abcdefghijklmnopqrstuvwxyz") != std::string::npos; 

: 간단한는 t에없는 s의 첫 번째 문자의 인덱스를 반환, 아마 s.find_first_not_of(t)입니다. 대문자 알파벳 문자도 일치 시키려면 해당 문자열에 26 자 이상을 추가해야합니다! 대신 <cctype>에서 <algorithm> 헤더와 std::isalpha에서 find_if의 조합을 사용할 수 있습니다 :

#include <algorithm> 
#include <cctype> 

struct non_alpha { 
    bool operator()(char c) { 
     return !std::isalpha(c); 
    } 
}; 

bool contains_non_alpha 
    = std::find_if(name.begin(), name.end(), non_alpha()) != name.end(); 

find_if 검색이 경우, 술어와 일치하는 값의 범위를 인수 여부를 반환하는 펑 non_alpha 알파벳이 아닌 문자입니다. find_if(name.begin(), name.end(), ...)name.end()을 반환하면 일치하는 것이 없습니다.

하지만 더 있습니다!

는이 <functional> 헤더로부터 어댑터를 사용하여 하나의 라이너로 이렇게하려면 다음

#include <algorithm> 
#include <cctype> 
#include <functional> 

bool contains_non_alpha 
    = std::find_if(name.begin(), name.end(), 
        std::not1(std::ptr_fun((int(*)(int))std::isalpha))) != name.end(); 

std::not1 그 입력의 논리 반전을 반환하는 함수 오브젝트를 생성한다; 함수에 대한 포인터를 std::ptr_fun(...)으로 지정하면, std::isalpha의 논리적 인 역수를 산출하기 위해 std::not1을 알 수 있습니다. 캐스트 (int(*)(int))std::isalpha의 오버로드를 선택하고 int (문자로 처리됨)을 받아 int (부울로 처리됨)을 반환합니다. 당신은 C++ 11 컴파일러를 사용할 수 있는지

은 또는, 람다를 사용하여 많은이 정리 :

#include <cctype> 

bool contains_non_alpha 
    = std::find_if(name.begin(), name.end(), 
        [](char c) { return !std::isalpha(c); }) != name.end(); 

[](char c) -> bool { ... }는 문자를 받아 들여 bool을 반환하는 함수를 의미한다. 우리의 경우 함수 몸체는 return 문으로 만 구성되어 있기 때문에 반환 유형을 생략 할 수 있습니다. 함수 객체를 훨씬 더 간결하게 지정할 수 있다는 점을 제외하면 이전 예제와 똑같은 방식으로 작동합니다.

그리고 (거의) 마지막으로 ... C++ (11) 당신은 또한 경기 수행하는 정규 표현식을 사용할 수 있습니다에서

:이 솔루션의

#include <regex> 

bool contains_non_alpha 
    = !std::regex_match(name, std::regex("^[A-Za-z]+$")); 

그러나 과정을 ...

없음 로케일 또는 문자 인코딩 문제를 해결합니다! isalpha()의 로케일 독립 버전의 경우, C++ 헤더 <locale> 사용해야 할 것 :

#include <locale> 

bool isalpha(char c) { 
    std::locale locale; // Default locale. 
    return std::use_facet<std::ctype<char> >(locale).is(std::ctype<char>::alpha, c); 
} 

이 이상적으로 우리가 char32_t을 사용하지만, 그것을 분류 할 수 ctype하지 않는 것, 그래서 우리는있어 char으로 붙어 있습니다. 우리가 로케일 문제에 대해 전적으로 춤을 출 수있는 운이 좋은 이유는 영어 글자에만 관심이 있기 때문입니다. UTF8-CPP이라는 편리한 헤더 전용 라이브러리가있어보다 안전한 인코딩 방식으로 처리해야합니다.

bool isalpha(uint32_t c) { 
    return (c >= 0x0041 && c <= 0x005A) 
     || (c >= 0x0061 && c <= 0x007A); 
} 

그런 다음 우리가 UTF-32 코드 포인트로 옥텟에서 basic_string::iterator에 적응하기 위해 utf8::iterator 어댑터를 사용할 수 있습니다 :

#include <utf8.h> 

bool contains_non_alpha 
    = std::find_if(utf8::iterator(name.begin(), name.begin(), name.end()), 
        utf8::iterator(name.end(), name.begin(), name.end()), 
        [](uint32_t c) { return !isalpha(c); }) != name.end(); 

를 들어 처음에 우리는 UTF-32 코드 포인트를 사용 isalpha() 우리의 버전을 정의 약간 안전의 비용으로 더 나은 성능, 당신은 utf8::unchecked::iterator를 사용할 수 있습니다

#include <utf8.h> 

bool contains_non_alpha 
    = std::find_if(utf8::unchecked::iterator(name.begin()), 
        utf8::unchecked::iterator(name.end()), 
        [](uint32_t c) { return !isalpha(c); }) != name.end(); 

이 일부 무효 INPU에 실패합니다 티.

이러한 방식으로 UTF8-CPP를 사용하면 호스트 인코딩이 UTF-8 또는 ASCII와 같은 호환되는 인코딩이라고 가정합니다. 이론적으로 이것은 여전히 ​​불완전한 해결책이지만, 실제로는 대부분의 플랫폼에서 작동 할 것입니다.

이 답변이 드디어 완료되기를 바랍니다.

+0

+1이 방법이 wchars 등에서 영어가 아닌 유니 코드를 사용하는 i18n 환경에서 작동하지만 훌륭한 반응을 보이는지 확실하지 않습니다. :) –

+1

name.find_first_not_of는 위치 또는 npos (-1)를 반환합니다. 이것은 결과가 bool에 캐스팅 될 때 항상 사실임을 의미합니다. 이것을 이해하려면 npos에 대해 테스트해야합니다. – flumpb

+0

@kisplit : 그것을 잡아 주셔서 감사합니다. 내 부분에 대한 감독. –

2

나는 CTYPE 라이브러리 조사 제안 : 예를 들어 http://www.cplusplus.com/reference/std/locale/ctype/

, 기능을 is (ctype.is 참조) 로케일에 민감한 방식으로 문자의 속성을 확인하는 방법입니다 :

#include <locale> 
using namespace std; 
bool is_alpha(char c) { 
    locale loc; 
    bool upper = use_facet< ctype<char> >(loc).is(ctype<char>::alpha, quote[0]); 
    return upper; 
} 
2
for (string::iterator it=name.begin(); it!=name.end(); ++it) 
    { 
    if ((*it) < 0x61 || (*it) > 0x71) 
     // string contains characters other than a-z 
    } 
+0

16 진수가 잘못되었습니다. 올바른 HEX 코드 (asciitable.com 참조)로 업데이트하십시오. 또한 'A'- 'Z'도 대문자로 사용할 수 있습니다. – CyprUS

+1

'A'와 ''Z ''를 사용하는 마법 부호는 사용하지 마십시오. 그러나이 조건은 시스템에서 [EBCDIC] (https://en.wikipedia.org/wiki/EBCDIC)처럼 거짓임을 유의하십시오. – Jarod42

5

부스트를 사용하는 경우 boost::algorithm::is_alpha 술어를 사용하여이 검사를 수행 할 수 있습니다. , 문서 상태로 "모두가() 술어에 의해 지정된 조건을 만족하는 컨테이너의 모든 요소를 ​​확인"

const char* text = "hello world"; 
bool isAlpha = all(text1, is_alpha()); 

업데이트 : 여기를 사용하는 방법입니다. is_alpha()는 실제로 문자에 대해 작동하기 때문에 all()에 대한 호출이 필요합니다.

희망, 도와 줬어.

+0

아마도'const char * test'를 의미했을 것입니다. – curiousguy

+0

@curiousguy : 감사합니다. 해결되었습니다. – Lev

+1

일반적인'all'과'is_alpha'라고 부르는 것을 보여줄 수 있습니다. 올바른'use namespace'가 없으면 일반적으로 권장되지 않습니다. 또한'text1'은 무엇입니까? –