首先,使用std::cin >> name
會如果用戶輸入John Smith
,則會失敗,因爲>>
會將輸入分割爲空白字符。您應該使用std::getline()
得到名稱:
std::getline(std::cin, name);
在這裏,我們去...
有許多的方法可以檢查字符串只包含字母字符。最簡單的是可能s.find_first_not_of(t)
,它返回第一個字符的s
指數,是不是在t
:
bool contains_non_alpha
= name.find_first_not_of("abcdefghijklmnopqrstuvwxyz") != std::string::npos;
這迅速變得麻煩,但是。要也匹配大寫字母字符,您必須爲該字符串添加26個字符!相反,你可能想從<cctype>
使用find_if
組合從<algorithm>
頭和std::isalpha
:
#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::not1
產生std::isalpha
的邏輯逆。演員(int(*)(int))
是在那裏選擇std::isalpha
的過載,其中需要int
(視爲字符)並返回int
(視爲布爾值)。
或者,如果你可以使用C++編譯器11,使用Lambda清除該漲了不少:
#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
功能。在我們的例子中,我們可以省略-> 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的方便標題庫,可以讓我們以更安全的編碼方式來做我們需要做的事情。首先我們定義的isalpha()
版本,使用UTF-32代碼點:
bool isalpha(uint32_t c) {
return (c >= 0x0041 && c <= 0x005A)
|| (c >= 0x0061 && c <= 0x007A);
}
然後我們可以使用utf8::iterator
適配器爲basic_string::iterator
從八位字節改編成UTF-32代碼點:
#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();
對於在稍微安全的成本更好的性能,可以使用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'。順便說一句,也可以嘗試與dvorak佈局。 –