2013-02-13 1 views
2

Можно ли обрабатывать исключения несоответствия типа данных в C?Как обрабатывать исключение несоответствия типа данных в C

В C++ и других языках более высокого уровня код обычно окружен try ... catch. Однако, поскольку в C нет механизма обработки исключений, как мы обрабатываем исключения несоответствия типа данных?

Например, предположим, что у меня есть программа, которая требует, чтобы пользователь вводил целое число. Если пользователь ошибочно попадает в буквенный символ, программа вылетает из строя. Как я могу позаботиться об этом в C?

Вот некоторые примеры кода:

#include "stdafx.h" 

void main() 
{ 
    int x = 0; 
    printf("Hello World!\n\n"); 
    printf("Please enter an integer: "); 
    scanf("%d", &x); 
    printf("\n"); 
    printf("The integer entered is %d", x); 
    printf("\n\n"); 
    printf("Press any key to exit!"); 
    getchar(); 
    getchar(); 
} 
+1

Проверка ошибок? Если ваша программа выйдет из строя на недопустимом входе, вы просто недостаточно проверяете ее. – Mat

+0

Может ли кто-нибудь дать мне пример, пожалуйста? Я совершенно новичок в языке программирования C. – Matthew

+1

Это совсем не C. Там, наверное, прим. четверть базиллиона примеров проверки возвращаемых значений функций, доступных в Интернете. – Mat

ответ

3

Я буду считать, что вы используете scanf для обработки входных данных. программа не должна терпеть крах. Вам нужно прочитать страницу руководства для scanf, а в возвращаемых значениях раздела указывается, что функция возвращает количество согласованных элементов. Вы сравниваете это число с ожидаемым. Если они отличаются, вы принимаете соответствующие меры.

EDIT

Некоторый код для Мэтью и Барта:

int i; 

if (scanf("%d", &i) == 1) 
{ 
    print("You have entered %d\n", i); 
} 
else 
{ 
    printf("You have entered an invalid number\n"); 
} 
-2

C использует возвращаемые значения и errno глобального, чтобы указать, если что-то пошло не так или нет. Таким образом, в вашем случае, давайте предположим, что (так как вы не предоставили какой-либо код), вы используете strtol перевести строку в целое число:

char *s = "1234"; 
int number; 
number = strtol(s, NULL, 10); 

Если число 0 и errno установлено, что-то пошло не так ,

Все функции в C работают таким образом. Чтобы сделать ваш код более надежным, прочитайте строки вместо чисел и преобразуйте их.

Фактически, есть много мест для исключений и кодов возврата. На мой взгляд, исключения должны использоваться для исключительного материала. И неправильный ввод данных не является исключительным (это скорее правило на самом деле ;-)), поэтому при подключении конвертировать не должно быть никаких исключений. Возможно, именно по этой причине у C# также есть метод TryParse.

+0

Итак, 0 больше не целое! –

+0

-1 не от меня, но 'atoi' действительно плохой пример –

+0

@JensGustedt будет' strtol' быть лучше? Дело было в том, чтобы использовать коды возврата вместо исключений. –

2

Добавление кода в то, что @EdHeal справедливо говорит выше. Образец Иллюстративный код:

INT основной (интермедиат ARGC, символ ** ARGV) {

int num; 
int ret; 

printf("Enter a number\n"); 
ret=scanf("%d",&num); 
/* For better clarity From the man page 
Upon successful completion, these functions shall return the number of successfully matched and assigned input items; this number can be zero in the event of an early matching failure */ 
printf("Number of items assigned %d",ret); 
printf("The input number is %d",num); 
return (EXIT_SUCCESS); 

}

Так вот для simplicty увидеть возвращаемое значение Scanf даного. После успеха, когда он читает целое число, он возвращает 1. В случае строк он читает 0.

Пример вывода а) Входное целое

Enter a number 
68 
Number of bytes read 1 
The input number is 68 
RUN SUCCESSFUL (total time: 2s) 

б) Введите строку

Enter a number 
yiy idfd 
Number of bytes read 0 
The input number is 2665608 
RUN SUCCESSFUL (total time: 4s) 
+0

Эта строка неверна 'printf (« Количество байтов, прочитанных% d », ret);' Это количество элементов в строке формата, как показано на вашем выходе. –

+0

@ EdHeal Yup! писал в спешке. Спасибо, что указали это. ! – rockstar

1

Несколько вариантов ввода данных:

Вы можете использовать зсапЕ, как упоминалось выше, но Я также рекомендую читать справочные страницы о getopt, getoptlong

Что касается проверки, вы можете попробовать regcomp, regexec, regerror, regfree. Например:

const char* pattern = "^[\\+,-]*[0-9]*$"; 
    regex_t regex; 
    int reti; 
    reti = regcomp(&regex, pattern, REG_EXTENDED); 
    if(reti){ 
    printf("error"); 
    exit(1); 
    } 
    reti = regexec(&regex, "34567", 0, NULL, 0); 
    if(reti == 0) { 
    printf("String matches pattern."); 
    }