简体   繁体   English

\\ r和\\ n或缓冲区刷新的问题

[英]Issues with \r and \n or Buffer Flushing

I have read in multiple places that \\n does not flush the buffer when used however in my code, which I will add at the end of this question, it seems to be doing just that or at least it seems that way from the output (maybe something else is going on in the background due to how I am executing my couts?). 我在多个地方都读过\\ n,但是在我的代码中使用时不会刷新缓冲区,我将在问题末尾添加它,它似乎只是在这样做,或者至少从输出看起来是这样的(也许由于我执行指令的原因在后台发生了其他事情?)。

Expected Output: 预期产量:

Mining Laser 1 cycle will complete in x seconds... 采矿激光1个周期将在x秒内完成...

Mining Laser 2 cycle will complete in x seconds... 采矿激光2周期将在x秒内完成...

Mining Laser 3 cycle will complete in x seconds... 采矿雷射3周期将在x秒内完成...

Mining Laser 4 cycle will complete in x seconds... 采矿激光4周期将在x秒内完成...

What I Get in the CLI: 我在CLI中得到的是:

Mining Laser 1 cycle will complete in x seconds... 采矿激光1个周期将在x秒内完成...

Mining Laser 2 cycle will complete in x seconds... 采矿激光2周期将在x秒内完成...

Mining Laser 3 cycle will complete in x seconds... 采矿雷射3周期将在x秒内完成...

Mining Laser 4 cycle will complete in x seconds... 采矿激光4周期将在x秒内完成...

Mining Laser 1 cycle will complete in x seconds... 采矿激光1个周期将在x秒内完成...

Mining Laser 2 cycle will complete in x seconds... 采矿激光2周期将在x秒内完成...

Mining Laser 3 cycle will complete in x seconds... 采矿雷射3周期将在x秒内完成...

Mining Laser 4 cycle will complete in x seconds... 采矿激光4周期将在x秒内完成...

Mining Laser 1 cycle will complete in x seconds... 采矿激光1个周期将在x秒内完成...

Mining Laser 2 cycle will complete in x seconds... 采矿激光2周期将在x秒内完成...

Mining Laser 3 cycle will complete in x seconds... 采矿雷射3周期将在x秒内完成...

Mining Laser 4 cycle will complete in x seconds... 采矿激光4周期将在x秒内完成...

What I want the output to do is remain in place, like those in the expected output example, and just update itself every the time loop in my code executes. 我希望输出执行的操作保持不变,就像预期输出示例中的输出一样,并且每次代码执行时都会自动更新。

Here is my code: 这是我的代码:

#include <iostream>
#include <Windows.h>
#include <string>
#include <vector>
#include <random>
#include <thread>
#include <future>

using namespace std; //Tacky, but good enough fo a poc D:

class mLaser
{
public:
    mLaser(int clen, float mamt, int time_left)
    {
        mlCLen = clen;
        mlMAmt = mamt;
        mCTime_left = time_left;
    }

    int getCLen()
    {
        return mlCLen;
    }

    float getMAmt()
    {
        return mlMAmt;
    }

    void setMCOld(int old)
    {
        mCTime_old = old;
    }

    void mCycle()
    {
        int mCTime_new = GetTickCount(); //Get current tick count for comparison to mCOld_time

        if (mCTime_old != ((mCTime_new + 500) / 1000)) //Do calculations to see if time has passed since mCTime_old was set
        {
            //If it has then update mCTime_old and remove one second from mCTime_left.
            mCTime_old = ((mCTime_new + 500) / 1000);
            mCTime_left -= 1000;
        }

        cur_time = mCTime_left; 
    }

    int getCTime()
    {
        return cur_time;
    }

    int getCTLeft()
    {
        return mCTime_left;
    }


private:
    int mlCLen; //Time of a complete mining cycle
    float mlMAmt; //Amoung of ore produced by one mining cycle (not used yet)
    int cur_time; //The current time remaining in the current mining cycle; will be removing this as it is just a copy of mCTime_left that I was going to use for another possiblity to make this code work
    int mCTime_left; //The current time remaining in the current mining cycle
    int mCTime_old; //The last time that mCycle was called
};

void sMCycle(mLaser& ml, int i1, thread& _thread); //Start a mining cycle thread

//Some global defines
random_device rd;
mt19937 gen(rd());

uniform_int_distribution<> laser(1, 3); //A random range for the number of mlaser entities to use
uniform_int_distribution<> cLRand(30, 90); //A random time range in seconds of mining cycle lengths
uniform_real_distribution<float> mARand(34.0f, 154.3f); //A random float range of the amount of ore produced by one mining cycle (not used yet)

int main()
{
    //Init some variables for later use
    vector<mLaser> mlasers; //Vector to hold mlaser objects
    vector<thread> mthreads; //Vector to hold threads
    vector<shared_future<int>> futr; //Vector to hold shared_futures (not used yet, might not be used if I can get the code working like this)

    int lasers; //Number of lasers to create
    int cycle_time; //Mining cycle time
    int active_miners = 0; //Number of active mining cycle threads (one for each laser)
    float mining_amount; //Amount of ore produced by one mining cycle (not used yet)

    lasers = laser(gen); //Get a random number
    active_miners = lasers; //Set this to that random number for the while loop later on

    //Create the mlaser objects and push them into the mlasers vector
    for (int i = 0; i < lasers; i++)
    {
        int clength = cLRand(gen);

        mlasers.push_back(mLaser(clength, mARand(gen), (clength * 1000)));

        //Also push thread obects into mthreads for each laser object
        mthreads.push_back(thread());
    }

    //Setup data for mining cycles
    for (int i = 0; i < mlasers.size(); i++)
    {
        int mCTime_start = GetTickCount(); //Get cycle start time
        mlasers.at(i).setMCOld(((mCTime_start + 500) / 1000));
    }

    //Print initial display for mining cycles
    for (int i = 0; i < mlasers.size(); i++)
    {
        cout << "Mining Laser " << i+1 << " cycle will complete in " << (mlasers.at(i).getCTLeft() + 500) / 1000 << " seconds...\n";
    }

    while (active_miners > 0)
    {   
        for (int i = 0; i < mlasers.size(); i++)
        {
            //futr.push_back(async(launch::async, [mlasers, i, &mthreads]{return sMCycle(mlasers.at(i), i + 1, mthreads.at(i)); }));
            async(launch::async, [&mlasers, i, &mthreads]{return sMCycle(mlasers.at(i), i + 1, mthreads.at(i)); }); //Launch a thread for the current mlaser object
            //mthreads.at(i) = thread(bind(&mLaser::mCycle, ref(mlasers.at(i)), mlasers.at(i).getCLen(), mlasers.at(i).getMAmt()));
        }

        //Output information from loops
        cout << " \r" << flush; //Return cursor to start of line and flush the buffer for the next info

        for (int i = 0; i < mlasers.size(); i++)
        {
            if ((mlasers.at(i).getCTLeft() != 0) //If mining cycle is not completed
            {
                cout << "Mining Laser " << i + 1 << " cycle will complete in " << (mlasers.at(i).getCTLeft() + 500) / 1000 << " seconds...\n";
            }

            else //If it is completed
            {
                cout << "Mining Laser " << i + 1 << " has completed its mining cycle!\n";
                active_miners -= 1;
            }
        }
    }


    /*for (int i = 0; i < mthreads.size(); i++)
    {
        mthreads.at(i).join();
    }*/


    //string temp = futr.get();
    //float out = strtof(temp.c_str(),NULL);

    //cout << out << endl;

    system("Pause");
    return 0;
}

void sMCycle(mLaser& ml, int i1,thread& _thread)
{
    //Start thread
    _thread = thread(bind(&mLaser::mCycle, ref(ml)));

    //Join the thread
    _thread.join();
}

Per Ben Voigt, it seems that \\r cannot be used in the way I am attempting to use it. 根据Ben Voigt的说法,\\ r似乎无法以我尝试使用的方式使用。 Does anyone have any other suggestions apart from Matthew's suggestion of clsing the command window each update? 除了Matthew建议每次更新都关闭命令窗口之外,还有人有其他建议吗? Maybe something in Boost or something new to c++11? 也许是Boost中的某些东西或c ++ 11的新东西?

Thanks. 谢谢。

You could try clearing the console after every execution with something like system("cls"); 您可以尝试在每次执行后使用诸如system(“ cls”)之类的东西清除控制台; here is a link to a post [ How can I clear console 这是文章的链接[ 如何清除控制台

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM