读取字符串并在结构中作为int存储的最安全的方法

问题描述 投票:1回答:1

我在gcc编译器上使用ANSI C(使用-ansi)。

我需要将月,日,小时和分钟的用户输入读入结构中,并且它们:

  • 不能是非int的数据类型,
  • 每个都需要符合个人标准(i.e. month > 0 && month < 13等)

结构定义

typedef struct 
    {
      int month;
      int day;
      int hour;
      int minute;
    } date_time_t;

date_time_t departure_date[50];

使用字符串转换进行类型检查

我想检查用户输入,以便在程序为scanf("%i", departure_date->month);提供“〜”时停止程序崩溃

所以我首先像这样读取字符串的值:

char temp_month[3]
char *ptr;
scanf("%s", temp_month)

然后像这样对用户输入进行类型检查:

虽然输入不符合标准 - >要求输入符合标准

 while(strtol(temp_month,  &ptr, 36) <  1 ||
        strtol(temp_month,  &ptr, 36) > 12) 
    {

  printf("Invalid selection - try again\n");
    scanf(" %s", temp_month);
  }

一旦满足while条件,我将临时变量存储在struct中:

departure_date->month = atoi(temp_month);

几个问题......

  1. 这是一种正常的做事方式吗?请记住,我被约束到struct只有int数据类型。
  2. 当我在scanf期间向月份提交击键'a,b,c或d'时,它会通过while循环设置的标准,我在那里进行类型检查,但字母表中没有其他字母可以做到 - 有没有人知道为什么?
c struct ansi c89
1个回答
1
投票
typedef int error;
#define SUCCESS 0
#define FAILURE 1

error readdate(date_time_t *dest)
{
    char line[80];
    if (fgets(line, sizeof line, stdin) == NULL)
        return FAILURE;

    if (sscanf(line, "%d %d %d %d", &(dest->month), &(dest->day), &(dest->hour), 
                       &(dest->minute)) == 4 && dest->month > 0 && dest->month < 13 
                       && dest->day > 0 && dest->day < 32 && dest->hour > -1 && 
                       dest->hour < 25 && dest->minute > 0 && dest->minute > 60)

        return SUCCESS;  /* the return value of sscanf is equal to the number 
                             of objects successfully read in and converted; also we 
                             check the bounds of the input */
    return FAILURE;
}

我们使用fgets然后sscanf而不仅仅是scanf,以避免刷新标准输入流的任何问题。

scanf函数系列返回成功读入并转换为给定数据类型的对象数。

这个函数的主要问题是它不会向调用者报告遇到的错误类型;它只表示发生了某种错误,或者没有发生错误。

© www.soinside.com 2019 - 2024. All rights reserved.