Логические функции в C ошибка "элемент управления может достигнуть конца непустой функции" - PullRequest
0 голосов
/ 10 июля 2020

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

Вот код, спасибо

#include <stdio.h>
#include <math.h>
#include <cs50.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

bool digit_validation (string s);

int main (int argc, string argv[])
{
    
    if((argc == 2) && (digit_validation(argv[1]) == true))
    {
        int key = atoi(argv[1]);
        printf("%i\n", key);
    }
    
    else
    {
        printf("Usage: ./caesar key\n");
    }

}

bool digit_validation (string s)
{
for (int i = 0, lenght = strlen (s); i < lenght; i++ )
{
    if(isdigit(s[i]))
    {
        return true;
        break;
    }
    
    else
    {
        return false;
    }
}
}

Ответы [ 2 ]

5 голосов
/ 10 июля 2020

Компилятор предупреждает, что функция digit_validation потенциально может "отвалиться" от функции - без возврата какого-либо значения. Если вызывающий использует значение, как это происходит в вашем коде, это приводит к неопределенному поведению .

Например, если вы передадите пустую строку "" , то length равно 0, а for l oop вообще не вводится.

digit_validation также имеет другие проблемы.

  • Если вы передать нулевой указатель, strlen будет проблематично c.

  • Фактически это не подтверждает, что все символы являются цифрами; как только будет найдено первое di git, функция вернется без проверки остальных.

Это можно исправить как:

bool digit_validation (string s)
{
    if (!s || !s[0]) return false;

    for (size_t i = 0; s[i]; ++i) {
        if(!isdigit((unsigned char)s[i])) return false;
    }
  
    return true;
}

Пара точек :

  • Аргумент isdigit (и все функции ctype в целом) необходимо привести к unsigned char, чтобы избежать поведения undefined в случае отрицательных значений .

  • Учитывая, что s - это строка , вы можете избежать использования strlen для вычисления длины и вместо этого использовать контрольный нулевой байт (strlen все таки проверит).

0 голосов
/ 10 июля 2020

Я думаю, что ваша вторая функция немного запутана, но это легко исправить:

bool digit_validation(string s) {
  size_t length = strlen(s);

  for (size_t i = 0; i < length; i++) {
    if (isdigit(s[i])) {
      return true;
    }
  }        

  return false;
}

Как другие заметили, ваш l oop мог быть пропущен, и это привело бы к конец функции, ничего не возвращая. Как правило, вы хотите структурировать свой код так, чтобы точки выхода были очевидны, а в вашем оригинале этого не было.

Это еще не определяет "все цифры", вам все равно придется исправить это, инвертировав лог c:

bool digit_validation(string s) {
  size_t length = strlen(s);

  if (!length) {
    return false;
  }

  for (size_t i = 0; i < length; i++) {
    if (!isdigit(s[i])) {
      return false;
    }
  }        

  return true;
}
...