unix 如何删除我在c++中用cout打印的行的最后一位数字?

r6hnlfcb  于 7个月前  发布在  Unix
关注(0)|答案(1)|浏览(92)

我正在写一个程序,我在CSV文件中打印我在程序的第一部分找到的值。在每一行我写5000个值,然后我开始一个新行:当我开始一个新行时,我想打印程序在文件中写了多少行的更新。我不想每次在程序中添加新行时都在终端上打印一个新行,比如:印刷线路:1\n打印行:2\n打印行:3\n但我想更新编号并保留“打印行:“

ofstream write_on_file("values.csv");
cout << "Printed lines:  ";
int cont = 0;
for(int i = 0; i < values.size(); i++) {
    if(i % 5000 == 0) {
        write_on_file << values[i] << endl;
        cont++;
        cout << "\b" << cont; //\b should delete the previous number
    } else write_on_file << values[i] << ",";
}
write_on_file.close();

字符串
不是打印“Printed lines:“然后删除最后一个数字并打印新的数字,而是“Printed lines:“只在for循环的最后一个值为的末尾打印。我在openSuse终端上用gcc编译。抱歉英语不好。

knpiaxh1

knpiaxh11#

终端控制-如何定位光标,更改颜色或字体等-不是 C++ 的一部分(也不是C语言的一部分)。然而,有一些东西几乎在任何地方都能工作,因为它们实际上已经有一百年的历史了,当时所有的打字和打印都是在打字机上进行的:他们有一辆带台板的马车(橡胶滚筒)固定和传送纸张的机器。一封信总是落在相对于机器的同一位置;为了使其落在纸上的不同位置上,水平移动是由滑架完成的,滑架能够左右移动足够远,打印将发生在纸的左边缘和右边缘之间的任何地方。纸;并且压纸卷筒将卷起(或者,当需要时,向下)以向下(或者,如果需要,向上)移动打印位置。
这种改变打印位置的模式-水平和垂直-一直保留到现代。在手动打字机上,这两种操作通常同时进行:一行已经完成,为了开始一个新的行,你必须同时做这两件事,向上推进纸张,向右重新定位滑架,这是用one quick operation of a long lever完成的。但是如果需要,滑架可以单独移动,而不需要旋转压板和前进到下一行。压板也可以单独移动,以便前进到一个新的行,这总是需要这样做,以插入一张新的纸。
在电传打字机中,这两种操作是由控制代码触发的,它们分别被称为 * 回车**、* 换行 * 或 * 换行 *。在20世纪60年代,这些操作的代码被标准化为ASCII的一部分,分别为13(回车)和10(换行)。
在世纪后半叶,电子终端逐渐取代了基于纸张的电传打字机;但其中许多人能够理解ASCII,包括控制字符,这就是为什么使用这个最小公分母的程序可以在绝大多数输出设备上工作。
更好的终端可以执行更精细的光标移动,但每个公司都有自己的控制方式,通常是通过发送专有的“控制序列”。在20世纪70年代,ANSI开始为这些功能的子集标准化control sequences,再次,现在许多终端都支持。下面我将使用其中的两个。下面的程序有两个部分,它们的不同之处仅在于光标的位置:第一个使用ASCII回车,第二个使用ANSI序列告诉终端记住并随后恢复光标位置。这两种方法都可以在Windows控制台和msys 2的mintty终端中使用,使用x86_64-pc-msys gcc编译。
我希望随机和线程代码不会分散注意力;输出才是这里最重要的。

#include <iostream>
#include <iomanip> // setw()
#include <random>
#include <thread> // just so that we can wait and see something

// Number of numbers, and if we want to see 10 outputs, we have the 
// following interval:
enum { NUM_COUNT = 1'000'000, PRINT_INTERVAL = NUM_COUNT/10 };
// Maximum number value, 
// Adjust the width with the max (could use log but overkill).
enum { MAX_NUM = 100'000, PRINT_WIDTH = 6 };
using namespace std;

int main()
{
    // the random number code is from
    // https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
    std::random_device rd;  // a seed source for the random number engine
    std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<> distrib(1, MAX_NUM);

    cout << "Carriage return method "
         << "(works virtually everywhere, including teletypes) : \n";
    cout << std::left; // number is left-aligned in "print box", looks nicer

    for (int i = 0; i < NUM_COUNT; i++)
    {
        auto num = distrib(gen);
        if (i % PRINT_INTERVAL == 0)
        {
            // '\r' moves the write position to the beginning of the line, but
            // does not advance the position to the next line. Subsequent output
            // will start to overwrite the current line, which is what you want.
            // (Ideally, you would like to go back only 
            // to the end of "Printed numbers:",
            // but that is not possible in a system independent manner.)
            cout << "\r";

            // setw() lets the next output operation
            // print spaces if the number has fewer digits so that 
            // previous longer numbers are overwritten.
            // flush to make sure the terminal sees it
            cout << "Printed numbers: " << setw(PRINT_WIDTH) << num << flush;
            this_thread::sleep_for(500ms); // so that we can see something
        }
    }
    cout << endl; // only one linefeed at the end.
    //-----------------------------------------------------------------------
    // second method for Windows Console

    cout << "ANSI terminal sequence method (works on most terminals):\n";

    // print that only once!
    cout << "Printed numbers: " << flush;   // flush: Make sure the terminal sees it. 
    // Let the terminal memorize the cursor position 
    // *after* "Printed numbers: ".
    cout << '\033' << "[s";      

    for (int i = 0; i < NUM_COUNT; i++)
    {
        auto num = distrib(gen);
        if (i % PRINT_INTERVAL == 0)
        {
            // Tell the terminal to move the cursor to the 
            // memorized position. It is always the same.
            cout << '\033' << "[u" << flush;
            cout << setw(PRINT_WIDTH) << num << flush;
            this_thread::sleep_for(500ms);
        }
    }
    cout << endl; // only one linefeed at the end.
}

字符串

相关问题