通过仔细选择比较,您可以简化'%' 的使用。不是检查month = 12 或month < 0,而是检查增量是否导致month > 12 或month < 1。这些是需要滚动到1 或12 的点。
例如,在将月份增加/减少某个值chg 的通用函数中,您只需将chg 添加到当前月份,然后应用测试,使用month = month % 12 更正month > 12 或通过设置month = month + 12 where month < 1,例如:
int monthchg (int *m, int chg)
{
*m += chg;
if (*m > 12) /* if month > 12, roll to month % 12 */
*m = *m % 12;
else if (*m < 1) /* if month < 1, add 12 to month */
*m += 12;
return *m;
}
将键盘置于非规范或原始模式并接受+/- 输入以更改月份或q 以退出的简短示例可能是:
#include <stdio.h>
#include <termios.h>
typedef struct {
struct termios old; /* orig keyboard settings */
struct termios new;
} kbmode;
kbmode *setkbmode (kbmode *k);
kbmode *restorekbmode (kbmode *k);
int monthchg (int *m, int chg)
{
*m += chg;
if (*m > 12) /* if month > 12, roll to month % 12 */
*m = *m % 12;
else if (*m < 1) /* if month < 1, add 12 to month */
*m += 12;
return *m;
}
int main (void) {
kbmode kb = { .old = {0} };
int dir, month = 6;
setkbmode (&kb); /* set kbd in raw-unbufered mode */
printf ("enter +/- to inc/decrement month ('q' to quit)\n");
for (;;) {
printf ("\n month : %2d : ", month);
fflush (stdout);
dir = getchar();
if (dir == '+')
monthchg (&month, 1);
else if (dir == '-')
monthchg (&month, -1);
else if (dir == 'q')
break;
else
puts ("invalid input - try again.");
}
putchar ('\n');
restorekbmode (&kb); /* restore original kbd settings */
return 0;
}
/* set keyboard in raw-unbufered mode */
kbmode *setkbmode (kbmode *k)
{
if (tcgetattr (0, &(k->old))) { /* save orig settings */
fprintf (stderr, "setkbmode() error: tcgetattr failed.\n");
return NULL;
} /* copy old to new */
k->new = k->old;
k->new.c_lflag &= ~(ICANON); /* new kbd flags */
k->new.c_cc[VTIME] = 0;
k->new.c_cc[VMIN] = 1;
if (tcsetattr (0, TCSANOW, &(k->new))) {
fprintf (stderr, "setkbmode() error: tcgetattr failed.\n");
return NULL;
}
return k;
}
kbmode *restorekbmode (kbmode *k)
{
/* reset original keyboard */
if (tcsetattr (0, TCSANOW, &(k->old))) {
fprintf (stderr, "restorekbmode() error: tcsetattr failed.\n");
return NULL;
}
return k;
}
使用/输出示例
$ ./bin/month_roll
enter +/- to inc/decrement month ('q' to quit)
month : 6 : -
month : 5 : -
month : 4 : -
month : 3 : -
month : 2 : -
month : 1 : -
month : 12 : -
month : 11 : -
month : 10 : +
month : 11 : +
month : 12 : +
month : 1 : +
month : 2 : -
month : 1 : -
month : 12 : -
month : 11 : -
month : 10 : +
month : 11 : +
month : 12 : +
month : 1 : +
month : 2 : +
month : 3 : q
查看一下,如果您还有其他问题,请告诉我。