翻过计数器跳过零

时间:2018-02-06 08:46:30

标签: c counter monthcalendar

也许是一个简单的问题,但我无法理解它。

我正在做某种月份柜台,想法是用户可以按 - 或+并仍然达到所需的月份: 例如我有: 今天是二月,所以这样的事情  用户按 -  2 1 12 11 10 9 ......  有些人选择+ 问题是我不希望零显示

old-time

这就是我提出的 - 它翻了12,然后是0或1 0 12 但我想摆脱零。 任何帮助将不胜感激:)

4 个答案:

答案 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 < 0month > 12。这些是需要转到month < 11的点。

例如,在用于递增/递减某个值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];
}