也许是一个简单的问题,但我无法理解它。
我正在做某种月份柜台,想法是用户可以按 - 或+并仍然达到所需的月份: 例如我有: 今天是二月,所以这样的事情 用户按 - 2 1 12 11 10 9 ...... 有些人选择+ 问题是我不希望零显示
old-time
这就是我提出的 - 它翻了12,然后是0或1 0 12 但我想摆脱零。 任何帮助将不胜感激:)
答案 0 :(得分:3)
这个问题很不清楚,但我会尝试
SINT16 tempVal = pDate->month + upDown;
if (tempVal < 0) {
/* if you are at negative 1 - assuming upDown is either (1,-1) */
tempVal += (12); //just add the cycle value
}
//pDate->month % (12 + 1);
pDate->month = (pDate->month % 12) + 1;//modulo by the cycle and then shift output
要明确模12会输出值(0 - 11)所以+1不应该包含在模数函数中
答案 1 :(得分:1)
如果tempVal变为零,则将月份视为12,否则将其增加1:
SINT16 tempVal = pDate->month + upDown;
if (tempVal == 0) {
pDate->month = 12;
}//if month becomes more than 12,ie 13
else if(tempVal %12 == 1)
{
pData->month = 1;
}
else
{
pDate->month = tempVal;
}
答案 2 :(得分:0)
通过仔细选择比较,您可以简化third
的使用。不是检查'%'
还是month = 12
,而是检查增量是否会导致month < 0
或month > 12
。这些是需要转到month < 1
或1
的点。
例如,在用于递增/递减某个值12
的月份的通用函数中,您只需将chg
添加到当前月份,然后应用测试,并使用chg
进行更正其中month = month % 12
或将month > 12
设置为month = month + 12
,例如:
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;
}
仔细看看,如果您有其他问题,请告诉我。
答案 3 :(得分:0)
我的建议是在代码中内部以[0,11]格式保存月份计数器,使用modulo(12)进行环绕。这很简单,易于理解代码。 然后编写一个函数,用于将内部表示[0,11]映射到用户想要查看的内容,即[1,12],无论何时打印或以某种方式向用户显示值。
int16_t display_month(int16_t month)
{
return month + 1;
}
在这种情况下返回月份+ 1很简单,但是在将N的计数映射到与[0,N-1]不匹配的情况的更一般情况下,我会使用数组来存储此映射。这样,映射实际上可以是任何东西,不必按顺序排列,并且事件不需要是整数。
int16_t display_month(int16_t month)
{
static int16_t index_to_month_map[] = {1,2,3,4,5,6,7,8,9,10,11,12};
return index_to_month_map[month];
}