【问题标题】:How to Handle Data Type Mismatch Exception in C如何在 C 中处理数据类型不匹配异常
【发布时间】:2013-01-28 18:04:57
【问题描述】:

是否可以在 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();
}

【问题讨论】:

  • 错误检查?如果您的程序因无效输入而崩溃,则说明您验证的不够充分。
  • 有人可以举个例子吗?我对 C 编程语言很陌生。
  • 这根本不是 C 特定的。大概有检查网络上可用函数的返回值的四分之一的例子。
  • @BartFriederichs 我贴了一些代码
  • @Matthew - 你需要检查scanf("%d", &x);的返回值。阅读手册页。

标签: c exception types mismatch


【解决方案1】:

我将假设您使用scanf 来处理输入。程序不应该崩溃。您需要阅读scanf 的手册页,并在返回值部分告诉您该函数返回匹配项的数量。您将此数字与预期的数字进行比较。如果它们不同,请采取适当的措施。

编辑

Matthew 和 Bart 的一些代码:

int i;

if (scanf("%d", &i) == 1)
{
    printf("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 不再是整数了?!
    • -1 不是我的,但atoi 确实是个坏例子
    • @JensGustedt strtol 会更好吗?重点是使用返回码而不是异常。
    • @BartFriederichs,当然。 strtol 有一种精确的方式来告诉你什么时候出了问题。 atoi 没有,因为 0 是有效输入。
    • @JensGustedt 究竟如何,我看不出文档有什么不同。它似乎使用errno。我更新了我的答案。
    【解决方案3】:

    将代码添加到@EdHeal 上面正确所说的内容中。 示例说明代码:

    int main(int argc, char** 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);
    

    }

    因此,为了您的简单起见,请查看 scanf 语句的返回值。成功后,即当它读取一个整数时,它返回 1 。如果是字符串,它读取 0 。

    样本输出 a ) 输入一个整数

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

    b) 输入一个字符串

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

    【讨论】:

    • 这一行不正确printf("Number of bytes read %d",ret); 是格式字符串中的项目数,如您的输出所示。
    • @EdHeal 是的!匆匆写下。感谢您指出。 !
    【解决方案4】:

    数据输入的几个选项:

    你可以使用上面提到的scanf,但我也建议阅读有关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.");
       }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-22
      • 2013-08-25
      • 2014-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      相关资源
      最近更新 更多