如何使用结构体接受用户输入以传递给另一个方法?

时间:2016-07-01 02:10:46

标签: c

我正在尝试创建一个结构来接受我的main方法中的用户输入,以便我可以将它传递给以后使用。我已经浏览了网站以获得结构帮助,但我所看到的是人们试图创建它作为它自己的功能;我想把它作为我主要的一部分。以下是我正在尝试为闹钟实现的一些细节:

  1. 获取所需闹钟时间的用户输入
  2. 将其与当地时间进行比较
  3. 以秒为单位递减计时器,并在达到闹钟时打印
  4. 关于重新声明/未声明的变量,我收到了轻微的编译错误。到目前为止,这是我的进步!

    #include <time.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <termios.h>
    #include <signal.h>
    
    struct sc_alarm_struct{
    int uhour, uminute, usecond;};
    
    struct sc_alarm_struct am;
    void sc_alarm();
    
    int main(int argc, char *argv[])
    {  
      if (argc > 1)
        {
            am.uhour = atoi(argv[1]);  
            am.uminute = atoi(argv[2]);
            am.usecond = atoi(argv[3]);
      }
    }
    
    void sc_alarm(int uhour, int uminute, int usecond)
    {
    
      struct tm *tm;
      time_t ctime;
      ctime = time(NULL);
      tm = localtime(&ctime);
    
      int alarm_total;
      int local_time_total;
      int difference;
    
      int chour = tm->tm_hour;
      int cminute = tm->tm_min;
      int csecond = tm->tm_sec;
    
      alarm_total = (uhour * 3600) + (uminute * 60) + usecond;
      local_time_total = (chour * 3600) + (cminute * 60) + csecond;
      difference = alarm_total - local_time_total;
    
      do
      {
        printf("%d seconds remaining.\n", difference);       
        difference--;
        sleep(1);
      }
      while(!(chour == am.uhour && cminute == am.uminute && csecond == am.usecond));
    
    printf("\nAlarm reached, wake up!\n\n");
    
    }
    

    任何建议或想法将不胜感激。

2 个答案:

答案 0 :(得分:0)

如果您可以提供构建信息以便其他人可以查看更多详细信息,那会更好。至于这个问题,alarm()是unistd.h中定义的一个函数(man 3 alarm,你会看到),你不能用这个名字声明一个变量,第51行的'u'是什么?

答案 1 :(得分:0)

很明显,您最大的挑战是熟悉struct语法并将结构作为参数传递给函数。两者都相对容易。如果您有struct(不是指向结构的指针),则使用'.'(点运算符)来访问每个成员。如果有指向结构的指针,则将使用'->'(箭头运算符)访问每个成员。这是结构的唯一两个访问规则。

将结构作为参数传递,您可以传递结构,例如

void sc_alarm (struct sc_alarm_struct astruct)

您将听到的内容称为按值传递,它会将结构传递给函数,函数将在该函数中接收结构的副本。对结构成员值所做的任何更改都不会反映在调用函数中 - 因为您在副本上运行,其中每个值的地址都不同于回到main

您可以将指针作为参数传递给结构,例如

void sc_alarm (struct sc_alarm_struct *astruct)

这里函数接收一个指向原始结构的指针。虽然它也可能是副本,但由于它是指针,因此副本仍然指向原始成员元素地址。现在所做的任何更改都将反映在调用者的结构值中。

由于您不是更改 sc_alarm功能中的成员值,因此您使用的内容并不重要。

您的下一个问题是在do {...} while (...);循环范围内包含的内容之一。这种选择通常由循环外必须看到的内容做出。如果循环外不需要任何内容​​,则可以在循环内声明所有值。但是,在您的情况下,您需要chour中的while (test)等,因此必须在循环本身之外声明这些。

完全放弃,并避免不必要地使用全球 struct sc_alarm_struct am;,您可以执行以下操作:

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

#include <time.h>
#include <unistd.h>

struct sc_alarm_struct
{ int uhour, uminute, usecond; };

void sc_alarm (struct sc_alarm_struct *astruct);

int main (int argc, char **argv)
{  
    struct sc_alarm_struct am;

    /* time from parameters (default 12:15:45) */
    am.uhour   = argc > 1 ? atoi (argv[1]) :  0;  
    am.uminute = argc > 2 ? atoi (argv[2]) : 49;
    am.usecond = argc > 3 ? atoi (argv[3]) : 15;

    sc_alarm (&am);

    return 0;  /* main is type (int) and provides a return */
}

void sc_alarm (struct sc_alarm_struct *astruct)
{
    int alarm_total, local_time_total, difference,
        chour, cminute, csecond;

    do {
        struct tm *tm;
        time_t ctime;
        ctime = time (NULL);
        tm = localtime (&ctime);

        chour = tm->tm_hour;
        cminute = tm->tm_min;
        csecond = tm->tm_sec;

        alarm_total = (astruct->uhour * 3600) + 
                      (astruct->uminute * 60) + 
                       astruct->usecond;

        local_time_total = (chour * 3600) + 
                           (cminute * 60) + 
                            csecond;

        if (local_time_total > alarm_total) {
            fprintf (stderr, "error: alarm time is in the past.\n");
            exit (EXIT_FAILURE);
        }
        difference = alarm_total - local_time_total;

        printf ("\r %4d seconds remaining.", difference);
        fflush (stdout);
        difference--;
        sleep (1);
    }
    while (!(chour   == astruct->uhour && 
            cminute == astruct->uminute && 
            csecond == astruct->usecond));

    printf ("\nAlarm reached, wake up!\n\n");
}

现在倒计时将在一条线上发生(假设您过去没有设置闹钟),然后在闹钟到达时退出,例如

示例使用/输出

$ ./bin/alarm 0 56 30
    0 seconds remaining.
Alarm reached, wake up!

尝试一下,让我知道这是不是你想要的。如果没有,我很高兴再试一次。