Подтвердить что ты не робот

Как тестировать строку только для букв

как я могу проверить строку против только допустимых символов, таких как буквы a-z?...

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);
}
4b9b3361

Ответ 1

Способ 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";

Ответ 2

Во-первых, использование 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 символов в эту строку! Вместо этого вы можете использовать комбинацию find_if из заголовка <algorithm> и std::isalpha из <cctype>:
#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(), то совпадения не найдено.

Но theres больше!

Чтобы сделать это как однострочный, вы можете использовать адаптеры из заголовка <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 (рассматривается как логическое).

Или, если вы можете использовать компилятор С++ 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 { ... } обозначает функцию, которая принимает символ и возвращает a bool. В нашем случае мы можем опустить возвращаемый тип -> bool, потому что тело функции состоит только из оператора return. Это работает так же, как и предыдущие примеры, за исключением того, что объект функции может быть указан гораздо более лаконично.

И (почти) наконец...

В С++ 11 вы также можете использовать регулярное выражение для выполнения соответствия:

#include <regex>

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

Но, конечно...

Ни одно из этих решений не затрагивает проблему языковой или кодировки символов! Для независимой от языка версии isalpha() вам необходимо использовать заголовок С++ <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. К счастью для нас, мы можем полностью танцевать по поводу локали, потому что вы, вероятно, интересуетесь только английскими буквами. Theres удобная библиотека только для заголовков, называемая 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();

Это приведет к ошибке при некорректном вводе.

Использование UTF8-CPP таким образом предполагает, что хост-кодирование является UTF-8 или совместимым кодированием, таким как ASCII. Теоретически это еще несовершенное решение, но на практике оно будет работать на подавляющем большинстве платформ.

Я надеюсь, что этот ответ окончательно завершен!

Ответ 3

Если вы используете Boost, вы можете использовать boost:: algorithm:: is_alpha предикат для выполнения этой проверки. Вот как его использовать:

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

Обновление: Как указано в документации, "all() проверяет все элементы контейнера, чтобы они удовлетворяли условию, заданному предикатом". Здесь нужен вызов all(), поскольку is_alpha() фактически работает с символами.

Надеюсь, я помог.

Ответ 4

Я бы предложил исследовать библиотеку 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;
}

Ответ 5

  for (string::iterator it=name.begin(); it!=name.end(); ++it)
  {
    if ((*it) < 0x61 || (*it) > 0x71) 
      // string contains characters other than a-z
  }

Ответ 6

Подход C++11 с использованием std :: all_of:

std::all_of(std::begin(name), std::end(name),
    [](char c){ return std::isalpha(c); });

std :: all_of вернет true, только если все элементы верны согласно предоставленной функции предиката.