【问题标题】:Pausing and restarting terminal output暂停和重启终端输出
【发布时间】:2014-04-22 03:50:51
【问题描述】:

我要做的是让终端打印出一个字符串,暂停,然后覆盖该字符串。但实际情况是,程序只是简单地打印出最终结果,而不显示第一个字符串。

我以为我可以使用sleep 来执行此操作,但它不起作用。为什么不呢?

#include <stdio.h>
#include <unistd.h>

int main(void){

    char message[] = "Hello there";
    int messageLength = sizeof(message);
    int i;

    printf("Hello, Dave.");
    sleep(2);
    for(i = 0; i < messageLength; i++)
        printf("\b");
    printf("Anyone there?\n");

    return 0;

}

更新版本,感谢回答:

#include <stdio.h>
#include <unistd.h>
#include <time.h>

void twprint(char* output, int outputLength, struct timespec* delay);
void twbackspace(int length, struct timespec* delay);

int main(void){

    char message1[] = "Hello, Dave.";
    char message2[] = "Are you there, Dave?";
    char message3[] = "I heard you talking in the pod.";
    char message4[] = "Dave?";
    struct timespec duration = { .tv_sec = 0, .tv_nsec = (100 * 1000 * 1000) }; 
    /* ^ .tv_nsec = one hundred million nanoseconds */

    twprint(message1, sizeof(message1)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message1)/sizeof(char), &duration);

    twprint(message2, sizeof(message2)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message2)/sizeof(char), &duration);

    twprint(message3, sizeof(message3)/sizeof(char), &duration);
    sleep(2);
    twbackspace(sizeof(message3)/sizeof(char), &duration);

    sleep(2);
    duration.tv_nsec *= 5;
    twprint(message4, sizeof(message4)/sizeof(char), &duration);

    printf("\n");

    return 0;

}

void twprint(char* output, int outputLength, struct timespec* delay){

    int i;
    struct timespec remaining; /* dummy parameter */

    for(i = 0; i < outputLength; i++){
        printf("%c", output[i]);
        fflush(stdout);
        nanosleep(delay, &remaining);
    }

}

void twbackspace(int length, struct timespec* delay){

    int i;
    struct timespec remaining; /* dummy parameter */

    for(i = 0; i < length; i++){
        printf("\b \b");
        fflush(stdout);
        nanosleep(delay, &remaining);
    }
}

【问题讨论】:

  • 您在 for 循环中删除了您的消息,这就是原因。
  • @valter,你不是说吗? :D
  • @valter 这就是为什么?你有没有读过 OP 想要做什么?
  • @JimBalter 他给了我一个很好的笑声。

标签: c io terminal sleep backspace


【解决方案1】:

printf 的输出是缓冲的,在缓冲区已满、打印换行符或调用 fflush(stdout) 之前不会打印到控制台。试试:

...
printf("Hello, Dave.");
fflush(stdout);
sleep(2);
...

维基百科提供了a good explanation 的标准流及其与缓冲相关的行为。

【讨论】:

    【解决方案2】:

    您需要刷新输出流以显示该行:

    printf("Hello, Dave.");
    fflush(stdout);
    

    顺便说一下,通常情况下,控制台输出会转到stderr。如果你这样做了,你就不必担心刷新(在许多平台上),因为stderr 通常是无缓冲的(所以输出是立即的),而stdout 通常是行缓冲的(所以输出不显示直到你写一个换行符)。

    【讨论】:

    • @AmadeusDrZaius stderr,顾名思义,用于错误输出;我认为向它写入除诊断之外的任何内容都是错误的。它默认为无缓冲以确保立即看到错误输出(即使程序崩溃)。但是,stdout 和 stderr 都可以重定向到设备或文件而不是终端,并且可以更改它们的缓冲(请参阅man7.org/linux/man-pages/man3/setbuf.3.html)。对于绝对必须到终端的输出,您可以使用 /dev/tty (stackoverflow.com/questions/8514735/…)
    猜你喜欢
    • 1970-01-01
    • 2015-06-18
    • 2014-07-26
    • 2012-08-26
    • 2017-12-01
    • 2013-07-06
    • 1970-01-01
    • 2013-02-10
    • 2015-12-21
    相关资源
    最近更新 更多