Как заставить isalpha перебирать каждый символ строки?

Мне сложно понять, как проверить каждый символ в ключевом слове (argv [1]). Я знаю, что, вероятно, упускаю что-то очень очевидное. :(

Я попытался сохранить строку в массив, объявив новый int, но все та же проблема.

//check to make sure 2nd argument is fully alphabetic
string keyword = argv[1];

for(int i = 0, n = strlen(keyword); i < n; i++)
{
    if(isalpha(keyword[i]))
    {
        printf("Success! \n");
        return 0;
    }
    else
    {
        printf("Invalid key, must be fully alphabetic. \n");
        return 1;
    }
}

Ожидаемый результат должен быть «Неверный ключ, должен быть полностью буквенным». для всего, что не полностью алфавитно. Вместо этого он работает только для начального символа, а не для всего ключевого слова.


person alexas    schedule 28.05.2019    source источник
comment
Это потому, что вы return из цикла, после первого теста. Пройдет или проиграет, вот и все, что нужно.   -  person Weather Vane    schedule 29.05.2019
comment
strlen() должен перебирать строку, чтобы найти конец, но затем вы перебираете строку в любом случае, проще и эффективнее использовать терминатор строки напрямую для завершения цикла: for( int i = 0; keyword[i] != 0; i++ )   -  person Clifford    schedule 29.05.2019
comment
Возможно, вас заинтересует сайт обмена стеками cs50.   -  person pmg    schedule 29.05.2019


Ответы (2)


Не выполняйте короткое замыкание (с помощью returning), если значение не является буквенным; сохраните печать Success и возврат 0, когда весь цикл завершится без выхода из-за неалфавитных символов:

for(int i = 0, n = strlen(keyword); i < n; i++)
{
    if(!isalpha(keyword[i]))
    {
        printf("Invalid key, must be fully alphabetic. \n");
        return 1;
    }
}
printf("Success! \n");
return 0;
person ShadowRanger    schedule 28.05.2019
comment
Спасибо. Мне пришлось переключить команды печати, потому что я думал, что !isalpha по какой-то причине не выполняется должным образом, и решил, что попробую. У меня возникают настоящие проблемы с повторением строки, чтобы проверить, что каждый символ является буквенным. Я думал, что это то, что делал if(isalpha(keyword[i]), но это не работает. Он по-прежнему говорит Success!, если начинается с буквенного символа и продолжается числовым символом. - person alexas; 29.05.2019
comment
@alexa: Вы говорите, что код выше все еще плохо себя ведет? Если так, то я могу только догадываться об использовании string, чего нет в C. Объявить keyword const char *, чтобы сохранить C. - person ShadowRanger; 29.05.2019
comment
Спасибо! Да, это была моя проблема. Ой. Теперь я понимаю. Работает отлично. :) - person alexas; 29.05.2019

Две проблемы

Не всегда выходить из цикла

@ShadowRanger

Используйте беззнаковые значения символов

isalpha(int x) определен для x в диапазоне unsigned char и EOF. Другие отрицательные char значения связаны с неопределенным поведением.

// if(!isalpha(keyword[i]))
if(!isalpha((unsigned char) keyword[i]))

С упрощенным циклом - strlen() не требуется.

int alexa_alpha_test(const char *keyword) {
  while (*keyword) {
    if(!isalpha((unsigned char) *keyword)) {
      printf("Invalid key, must be fully alphabetic. \n");
      return 1;
    }
    keyword++; 
  }
  printf("Success! \n");
  return 0;
}
person chux - Reinstate Monica    schedule 29.05.2019
comment
isalpha(int x) определен для x в диапазоне unsigned char и EOF. Другие отрицательные char значения представляют собой неопределенное поведение. И еще одна причина никогда и никогда не использовать ошибочный typedef char *string; bodge CS50. - person Andrew Henle; 29.05.2019
comment
@AndrewHenle Да, CS50 string keyword, похоже, увековечивает неправильное понимание строки, поскольку keyword не является строкой C, а указателем на (надеюсь) строку - с символами знака IDB. Больше обычных проблем с определением типа указателя. - person chux - Reinstate Monica; 29.05.2019
comment
@chux О, хорошо, спасибо за подробное объяснение! В этом гораздо больше смысла. Теперь работает отлично. Я ценю помощь и разъяснения. - person alexas; 29.05.2019