먼저, 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와 같은 호환되는 인코딩이라고 가정합니다. 이론적으로 이것은 여전히 불완전한 해결책이지만, 실제로는 대부분의 플랫폼에서 작동 할 것입니다.
이 답변이 드디어 완료되기를 바랍니다.
숙제 인 경우 ... 표시해야합니다. –
무엇이 당신의 질문입니까? 코드가 잘못 되었습니까? 아니면 누락 된 코드입니까? 어떤 경우에, 무엇? –
'* it'. btw 또한 dvorak 레이아웃으로 시도해보십시오. –