转换时间 如何改进我的代码?

标签 c

刚刚开始编程,因此任何建议或建设性批评将不胜感激。我很确定有方法可以缩短这个时间,但我只是不知道如何做,特别是使用函数。

#include <stdio.h>
#include <stdlib.h>

int input, check = 1, ans;
int menu ();
int convert24(int hour, int min, int sec, int meridiem);
int convert12(int hour, int min, int sec, int meridiem);
int result(int hour, int min, int sec, int meridiem);
void processAnother();

int main()
{
do
{
    menu();
    processAnother();
    system("cls");
}while (ans = 'y');

}
int menu ()
{
    int hour, min, sec, meridiem;
    printf("[1] Convert to 24-hour notation\n");
    printf("[2] Convert to 12-hour notation\n");
    printf("[3] Quit\n");
    scanf("%d", &input);


    switch(input)
    {
        case 1 :
            {
                printf("Enter hours (1-12):minute(1-59):seconds(1-59): ");
                scanf("%d %d %d", &hour, &min, &sec);
                printf("[1] AM or [2] PM: ");
                scanf(" %d", &meridiem);
                return convert24(hour, min, sec, meridiem);
                break;
            }
        case 2 :
            {
                printf("Enter hours(1-24):minute(1-59):seconds(1-59): ");
                scanf("%d %d %d", &hour, &min, &sec);
                printf("[1]AM or [2]PM: ");
                scanf(" %d", &meridiem);
                return convert12(hour, min, sec, meridiem);
                break;
            }
        default :
            {
                printf("Goodbye :)");
                exit(0);
            }
    }
}
int convert24(int hour, int min, int sec, int meridiem)
{
    if ((hour > 12 || hour < 0))
    {
        printf("\nError! Invalid Hour\n");
        check = 0;
    }
    if ((min >= 60 || min <0))
    {
        printf("\nError! Invalid Minute\n");
        check = 0;
    }
    if ((sec >= 60 || sec <0))
    {
        printf("\nError! Invalid Second\n");
        check = 0;
    }
    if (meridiem > 2 || meridiem < 0)
    {
        printf("\nError! Invalid Meridiem\n");
        check = 0;
    }
    if (check == 1)
    {
        if (meridiem == 1)
        {
            if (hour == 12)
            {
                hour = 0;
                result(hour, min, sec, meridiem);
            }
            else
            {
                result(hour, min, sec, meridiem);
            }
        }
        else if (meridiem == 2)
        {
            if (hour == 12)
            {
                hour = 12;
                result(hour, min, sec, meridiem);
            }
            else
            {
                hour+=12;
                result(hour, min, sec, meridiem);
            }
        }
    }
    processAnother();
}
int convert12(int hour, int min, int sec, int meridiem)
{
    if ((hour > 24 || hour < 0))
    {
        printf("\nError! Invalid Hour\n");
        check = 0;
    }
    if ((min >= 60 || min <0))
    {
        printf("\nError! Invalid Minute\n");
        check = 0;
    }
    if ((sec >= 60 || sec <0))
    {
        printf("\nError! Invalid Second\n");
        check = 0;
    }
    if (meridiem > 2 || meridiem < 0)
    {
        printf("\nError! Invalid Meridiem\n");
        check = 0;
    }
    if (check == 1)
    {
        if (meridiem == 1)
        {
            if (hour <= 12)
            {
                result(hour, min, sec, meridiem);
            }
            else
            {
                hour -= 12;
                result(hour, min, sec, meridiem);
            }
        }
        else if (meridiem == 2)
        {
            if (hour <= 12)
            {
                result(hour, min, sec, meridiem);
            }
            else
            {
                hour -= 12;
                result(hour, min, sec, meridiem);
            }
        }
    }
    processAnother();
}
int result(int hour, int min, int sec, int meridiem)
{
    char *x;
    int y;
    if(meridiem == 1)
    {
       x = "AM";
    }
    else if (meridiem == 2)
    {
       x = "PM";
    }
    if (input == 1)
    {
        y = 24;
    }
    else if (input == 2)
    {
        y = 12;
    }
    printf("The %d-hr Notation is : %d:%d:%d %s\n",y, hour, min, sec, x);
    return;
}
void processAnother()
{
    printf("Process another [y/n]");
    scanf("%c", &ans);
    return;
}

非常感谢。

最佳答案

ans,用作char,但声明为int,它可以工作,但很难看,也不要滥用全局变量、inputcheckans 可以在其他地方声明,其中一些甚至不需要声明。

convert12()convert24() 上,您在第 20 行执行相同的操作,编写一个函数,如果出现错误,则返回 0否则为 1。

我通常将 main() 函数放在文件的底部,这样我就不必对文件中的所有其他函数进行原型(prototype)设计

不要在每次调用大多数函数时传递 hourminsecmeridiem,而是创建一个包含每个元素的 struct 并传递它的指针。

main() 应该这样声明 main(void) 参见 here了解更多信息

对于这个,我将使用多个步骤

第一:

int convert12(int hour, int min, int sec, int meridiem)
{
    if ((hour > 24 || hour < 0))
    {
        printf("\nError! Invalid Hour\n");
        check = 0;
    }
    if ((min >= 60 || min <0))
    {
        printf("\nError! Invalid Minute\n");
        check = 0;
    }
    if ((sec >= 60 || sec <0))
    {
        printf("\nError! Invalid Second\n");
        check = 0;
    }
    if (meridiem > 2 || meridiem < 0)
    {
        printf("\nError! Invalid Meridiem\n");
        check = 0;
    }
    if (check == 1)
    {
        if (meridiem == 1)
        {
            if (hour <= 12)
            {
                result(hour, min, sec, meridiem);
            }
            else
            {
                hour -= 12;
                result(hour, min, sec, meridiem);
            }
        }
        else if (meridiem == 2)
        {
            if (hour <= 12)
            {
                result(hour, min, sec, meridiem);
            }
            else
            {
                hour -= 12;
                result(hour, min, sec, meridiem);
            }
        }
    }
    processAnother();
}

可以变成:

int convert12(my_time_t *time, int input)
{
  if (are_time_correct(time, input))
    {
      if (time->meridiem == 1)
        {
          if (time->hour <= 12)
            {
            }
          else
            {
              time->hour -= 12;
            }
        }
      else if (time->meridiem == 2)
        {
          if (time->hour <= 12)
            {
            }
          else
            {
              time->hour -= 12;
            }
        }
    }
  result(time, input);
  processAnother();
}

我遵循了之前的建议,并将 result 的调用移到了末尾

我知道它不会像这样工作,但你现在可以这样写:

int convert12(my_time_t *time, int input)
{
  if (are_time_correct(time, input))
    {
      if (time->meridiem == 1 && time->hour > 12)
        {
          time->hour -= 12;
        }
      else if (time->meridiem == 2 && time->hour > 12)
        {
          time->hour -= 12;
        }
    }
  result(time, input);
  processAnother();
}

就在我们测试 meridiem 是否在 1 和 2 之间之前,我们可以像这样编写这个函数

int convert12(my_time_t *time, int input)
{
  if (are_time_correct(time, input) && time->hour > 12)
    {
      time->hour -= 12;
    }
  result(time, input);
  processAnother();
}

对convert24()执行相同的过程

如果您遵循我的所有指示,您应该得到如下内容:

#include <stdio.h>
#include <stdlib.h>

// time_t aleardy exist so I used my_time_t instead
typedef struct my_time_s
{
  int hour;
  int min;
  int sec;
  int meridiem;
} my_time_t;


void processAnother(void)
{
  char ans;

  printf("Process another [y/n]");
  // note the space at the start
  // that means to discard all whitespace
  // exit if ans different than 'y'
  if (scanf(" %c", &ans) <= 0 || ans != 'y')
    exit(0);
}

// don't prototype your fuctions with int if they return nothing
void result(my_time_t *time, int input)
{
  // use variable with explicit name
  char *meridiem;
  int notation;

  if(time->meridiem == 1)
    {
      meridiem = "AM";
    }
  else if (time->meridiem == 2)
    {
      meridiem = "PM";
    }

  // it's the same as old notation if you don't know the << operator search what bitshift is on the internet
  // y = 6 << input <==> y = 6 * 2 ^ input
  // so if input = 1 : y = 6 * 2 ^ 1 = 12
  //    if input = 2 : y = 6 * 2 ^ 2 = 24
  notation = 6 << input;
  printf("The %d-hr Notation is : %d:%d:%d %s\n", notation, time->hour, time->min, time->sec, meridiem);
  return;
}

int are_time_correct(my_time_t *time, int input)
{
  int check = 1;

  // double parenthesis are not needed
  // (6 << input) can be equal at 12 or 24 in function of input see above for more informations
  if (time->hour > (6 << input) || time->hour < 0)
    {
      printf("\nError! Invalid Hour\n");
      check = 0;
    }
  if (time->min >= 60 || time->min < 0)
    {
      printf("\nError! Invalid Minute\n");
      check = 0;
    }
  if (time->sec >= 60 || time->sec < 0)
    {
      printf("\nError! Invalid Second\n");
      check = 0;
    }
  // i don't think the meridiem can be below 0 so I replace (time->meridiem < 0) by (time->meridiem < 1)
  if (time->meridiem > 2 || time->meridiem < 1)
    {
      printf("\nError! Invalid Meridiem\n");
      check = 0;
    }
  return (check);
}

int convert24(my_time_t *time, int input)
{
  if (are_time_correct(time, input) && time->hour == 12)
    {
      // if time->meridiem == 1 :
      //    time->hour = 12 * (1 - 1) = 0
      // if time->medriem == 2 :
      //    time->hour = 12 * (2 - 1) = 12
      time->hour = 12 * (time->meridiem - 1);
    }
  result(time, input);
  // processAnother(); is not needed you already do it on the main loop
  return (0);
}

int convert12(my_time_t *time, int input)
{
  if (are_time_correct(time, input) && time->hour > 12)
    {
      time->hour -= 12;
    }
  result(time, input);
  // processAnother(); is not needed you already do it on the main loop
  return (0);
}

int menu(void)
{
  int input;
  my_time_t time;

  // string concatenation
  printf("[1] Convert to 24-hour notation\n"
     "[2] Convert to 12-hour notation\n"
     "[3] Quit\n");

  if (scanf(" %d", &input) <= 0)
    {
      printf("\nWrong input\n");
      input = 3;
    }


  switch(input)
    {
    case 1 :
      {
    printf("Enter hours (1-12):minute(1-59):seconds(1-59): ");
    if (!scanf(" %d", &time.hour) <= 0 ||
        !scanf(" %d", &time.min) <= 0 ||
        !scanf(" %d", &time.sec) <= 0)
      {
        printf("\nWrong input\n");
        return (1);
      }
    printf("[1] AM or [2] PM: ");
    if (!scanf(" %d", &time.meridiem) <= 0)
      {
        printf("\nWrong input\n");
        return (1);
      }
    return convert24(&time, input);
    break;
      }
    case 2 :
      {
    printf("Enter hours(1-24):minute(1-59):seconds(1-59): ");
    if (scanf(" %d", &time.hour) <= 0 ||
        scanf(" %d", &time.min) <= 0 ||
        scanf(" %d", &time.sec) <= 0)
      {
        printf("\nWrong input\n");
        return (1);
      }
    printf("[1]AM or [2]PM: ");
    if (scanf(" %d", &time.meridiem) <= 0)
      {
        printf("\nWrong input\n");
        return (1);
      }
    return convert12(&time, input);
    break;
      }
    default :
      {
    printf("Goodbye :)");
    exit(0);
      }
    }
  return (0);
}

// function without parameters are declared with void
int main(void)
{
  // a while loop is simpler imo
  while (1)
    {
      // if menu() return 1 it means the user enter a wrong input
      // in that case no need to call processAnother()
      if (!menu())
    {
      processAnother();
    }
      // DON'T USE SYSTEM NEVER EVER SEE HERE FOR MORE INFO https://stackoverflow.com/questions/19913446/why-should-the-system-function-be-avoided-in-c-and-c
      // anyway some shell (such as mine) don't reconise `cls` and use clear instead
      system("cls");
    }
  return (0);
}

您也没有测试 scanf 是否返回某些内容,在某些情况下您的程序会出现段错误

关于转换时间 如何改进我的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40083451/

相关文章:

c - 在嵌入式系统上解析字符串的有效方法是什么?

c - bool 方法的段错误 11

c - HDF5:更新整数表中的单元格

c++ - C:使用 strtol endptr 永远不会为 NULL,无法检查值是否仅为整数?

C:单文件字符串替换程序

C - 小数字的浮点舍入

c - 在 C : prevent generating stack pointer initialization 中写入引导扇区

c - 如何为指定的子进程分配一个CPU?

计算c中二维数组的最小值和最大值

c++ - 为什么函数在python中是静态的?