【问题标题】:(Chrono Time) Minute tick detection error(计时时间)分钟刻度检测错误
【发布时间】:2020-04-08 17:21:22
【问题描述】:

我的代码中有一个 if 语句,它应该检测我的 chrono::duration 是否超过一分钟的运行时间。当 if 语句变为真时,它应该打印“Tick!” 一次,但我的程序会打印“Tick!”每次 delta__time 超过一分钟,即使我从中减去 60 秒。您可能需要查看照片才能更好地了解问题。我仍在努力解释事情,这只是我在网站上的第二篇文章。如何让我的代码每分钟只打印一次刻度?非常感谢。

int main()
{
    // Create Screen Buffer
    wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
    HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
    //SetConsoleActiveScreenBuffer(hConsole);
    DWORD dwBytesWritten = 0;

    wstring numberSystem[10] = {
    };

    while (1)
    {
        tp2 = chrono::system_clock::now();
        chrono::duration<long double, ratio<60>> delta__time = tp2 - tp1;

    if (delta__time >= 60s)
        {
            delta__time -= 60s;
            cout << "Tick!\t" << delta__time.count() << endl;
        }
        else {
            cout << delta__time.count() << endl;
        }
        // Handle change in time here.
    }

    return 0;
}

Chrono time minute tick detection error

【问题讨论】:

    标签: c++ chrono


    【解决方案1】:

    正如@drescherjm 所说,您的问题是-= 60s; 被丢弃,因为您每次迭代都会重新计算增量时间。

    using namespace std::literals;
    
    auto start_time = std::chrono::system_clock::now();
    long ticks = 0;
    while (1)
    {
      auto current_time = std::chrono::system_clock::now();
      std::chrono::duration<long double, std::ratio<60>> delta_time = current_time - start_time;
      delta_time -= ticks * 60s; // note that `ticks` adds up.
    
      if (delta_time >= 60s)
      {
        ++ticks;
        std::cout << "Tick!\t" << delta_time.count() << std::endl;
      } else {
        std::cout << delta_time.count() << std::endl;
      }
      // Handle change in time here.
    }
    

    我将start_time 保留为未更改的开始时间,current_time 同上,而不是像添加到tp1 一样。它使思考这些变量真正简单。

    【讨论】:

    • 最后一段,合理,尽管我个人更喜欢修改“开始”条件,以便算法(例如)随着时间的推移有效地保持不变。你只是“从头开始”。更容易测试和合理化,也减少了一个心理跟踪变量
    • @AsteroidsWithWings:很长一段时间内没有(签名:/)溢出。 ;-)
    • 最简单的解决方案往往最难找到。非常感谢!我知道我哪里出错了。如果 cout 没有告诉我它是什么,我可能已经抓住了它,而且当你在更概念的层面上处理标量时,更难想象正在发生的事情,而不是像我所做的那样从视觉上理解它用更简单的程序。附言我和你们一起修改开始条件而不是跟踪滴答声,而且你们还获得了溢出保护。 :)
    【解决方案2】:

    要关闭这篇文章...我继续往 tp1 变量中添加 60 秒,每发生一分钟的滴答声。谢谢! :)

    这是最终代码。

    #include <iostream>
    #include <chrono>
    using namespace std;
    
    #include <Windows.h>
    
    int nScreenWidth = 240;
    int nScreenHeight = 80;
    
    int nMapWidth = 8;
    int nMapHeight = 5;
    
    int main()
    {
        // Create Screen Buffer
        wchar_t* screen = new wchar_t[nScreenWidth * nScreenHeight];
        HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE, 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL);
        SetConsoleActiveScreenBuffer(hConsole);
        DWORD dwBytesWritten = 0;
    
        // Current Time
        int hourDoubleDigit = 1;
        int hourSingleDigit = 2;
        int minuteDoubleDigit = 0;
        int minuteSingleDigit = 0;
    
        // Character Mapping
        wstring numberSystem[10] = {
        };
    
        numberSystem[0] += L"########"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";
        numberSystem[0] += L"##   ###"; numberSystem[1] += L"      ##"; numberSystem[2] += L"      ##";
        numberSystem[0] += L"## ## ##"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";
        numberSystem[0] += L"###   ##"; numberSystem[1] += L"      ##"; numberSystem[2] += L"##      ";
        numberSystem[0] += L"########"; numberSystem[1] += L"      ##"; numberSystem[2] += L"########";
    
        numberSystem[3] += L"########"; numberSystem[4] += L"##    ##"; numberSystem[5] += L"########";
        numberSystem[3] += L"      ##"; numberSystem[4] += L"##    ##"; numberSystem[5] += L"##      ";
        numberSystem[3] += L"########"; numberSystem[4] += L"########"; numberSystem[5] += L"########";
        numberSystem[3] += L"      ##"; numberSystem[4] += L"      ##"; numberSystem[5] += L"      ##";
        numberSystem[3] += L"########"; numberSystem[4] += L"      ##"; numberSystem[5] += L"########";
    
        numberSystem[6] += L"########"; numberSystem[7] += L"########"; numberSystem[8] += L"########"; numberSystem[9] += L"########";
        numberSystem[6] += L"##      "; numberSystem[7] += L"      ##"; numberSystem[8] += L"##    ##"; numberSystem[9] += L"##    ##";
        numberSystem[6] += L"########"; numberSystem[7] += L"      ##"; numberSystem[8] += L"########"; numberSystem[9] += L"########";
        numberSystem[6] += L"##    ##"; numberSystem[7] += L"      ##"; numberSystem[8] += L"##    ##"; numberSystem[9] += L"      ##";
        numberSystem[6] += L"########"; numberSystem[7] += L"      ##"; numberSystem[8] += L"########"; numberSystem[9] += L"########";
    
        // Keeping Track of System Time
        auto tp1 = chrono::system_clock::now();
        auto tp2 = chrono::system_clock::now();
    
        auto TickInterval = 60s;
    
        while (1)
        {
            for (int xy = 0; xy <= nScreenWidth * nScreenHeight; xy++) screen[xy] = ' ';//To prevent buggy character spawning...
            // You don't always have to write this above line if you're already making use of writing characters to every space in the screen, but I'm not!
    
    
            // Let the program know a minute has passed... (Time passes too much too often)
            tp2 = chrono::system_clock::now();
            chrono::duration<long double> delta__time = tp2 - tp1;
            bool TICKhasOCCURED = false;
    
            if (delta__time >= TickInterval)
            {
                tp1 += TickInterval;
                TICKhasOCCURED = true;
            }
    
            if (TICKhasOCCURED)
            {
                if (minuteSingleDigit >= 9)
                {
                    if (minuteDoubleDigit >= 5)
                    {
    
                        if (hourSingleDigit >= 9 && hourDoubleDigit == 0)
                        {
                            hourDoubleDigit++;
                            hourSingleDigit = 0;
                            minuteDoubleDigit = 0;
                            minuteSingleDigit = 0;
                        }
                        else if (hourSingleDigit >= 2 && hourDoubleDigit == 1)
                        {
                            hourDoubleDigit = 0;
                            hourSingleDigit = 1;
                            minuteDoubleDigit = 0;
                            minuteSingleDigit = 0;
    
                        }
                        else {
                            hourSingleDigit++;
                            minuteDoubleDigit = 0;
                            minuteSingleDigit = 0;
                        }//After 59 minutes check the hour and change it.
                    }
                    else {
                        minuteDoubleDigit++;
                        minuteSingleDigit = 0;
                    }
                }
                else {
                    minuteSingleDigit++;
                }
            }
    
    
            // The Current Time is then drawn out using the mapped characters.
            for(int ix = 0; ix < nMapWidth; ix++)
                for (int iy = 0; iy < nMapHeight; iy++)
                {
                    screen[00 + ix + (nScreenWidth * iy)] = numberSystem[hourDoubleDigit][ix + (nMapWidth * iy)];
                    screen[10 + ix + (nScreenWidth * iy)] = numberSystem[hourSingleDigit][ix + (nMapWidth * iy)];
                    screen[20 + ix + (nScreenWidth * iy)] = numberSystem[minuteDoubleDigit][ix + (nMapWidth * iy)];
                    screen[30 + ix + (nScreenWidth * iy)] = numberSystem[minuteSingleDigit][ix + (nMapWidth * iy)];
                }
    
    
            //Debug
            //cout << hourDoubleDigit << "\t" << hourSingleDigit << "\t" << minuteDoubleDigit << "\t" << minuteSingleDigit << endl;
            TICKhasOCCURED = false;
    
            screen[nScreenWidth * nScreenHeight-1] = '\0';
            WriteConsoleOutputCharacter(hConsole, screen, nScreenWidth * nScreenHeight, { 0,0 }, &dwBytesWritten);
        }
    
        return 0;
    }
    

    【讨论】:

      【解决方案3】:

      delta__time 在每次循环迭代开始时都会重新计算,因此对其进行的更改不会产生任何持久影响(尽管它确实会影响紧随其后的cout,这就是您的值看起来很低的原因)。

      您可能希望将 60s 添加到 tp1(或将其设置为 now(),尽管这会导致错误)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-08
        • 2019-05-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多