简体   繁体   English

函数printf()打印退格问题

[英]Function printf() to print backspace problem

There are two programs and they get different results, but I don't understand why. 有两个程序,它们得到不同的结果,但是我不明白为什么。 Here is the first: 这是第一个:

int main()
{
    printf("12345");
    fflush(stdout);
    printf("\b\b");
    fflush(stdout);
    return 0;
}

The result is: 123 . 其结果是: 123 Then the second: 然后第二个:

int main()
{
    printf("12345");
    fflush(stdout);
    sleep(1);
    printf("\b\b");
    fflush(stdout);
    return 0;
}

but the result is: 12345 . 但结果是: 12345

Why does the sleep call make the second result different when I expect a "123" result? 为什么当我期望结果为“ 123”时,睡眠调用会使第二个结果有所不同? The code was running in the CLion. 该代码在CLion中运行。 and My OS is macOS, if it matters. 如果需要的话,我的操作系统是macOS。

Your code first displays "12345" and then displays "123". 您的代码首先显示“ 12345”,然后显示“ 123”。 Without the sleep , the "12345" is displayed for too little time to be visible. 如果没有sleep ,则显示“ 12345”的时间太短而看不到。 With the sleep , you can see the "12345" for about a second before the "4" and "5" are erased. 有了sleep ,您可以在删除“ 4”和“ 5”之前看到“ 12345”大约一秒钟。

Depending on the Terminal, '\\b' might "erase" a character or only move the cursor to the left. 根据终端的不同, '\\b'可能会“擦除”一个字符或仅将光标移到左侧。 To have a foolproof solution, use: 要获得万无一失的解决方案,请使用:

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

int main(void)
{
    printf("12345");
    fflush(stdout);
    sleep(1);
    printf("\b\b  \b\b");
    fflush(stdout);
}

With the original code (called bs97 , compiled from bs97.c ), and with my command line prompt Osiris JL: , I get the output: 使用原始代码(称为bs97 ,从bs97.c编译),并使用命令行提示符Osiris JL: bs97.c获得输出:

Osiris JL: bs97
123Osiris JL:

Note that the new prompt has overwritten the 45 . 请注意,新提示已覆盖45 You can see that if you add putchar('\\n'); 您可以看到,如果添加putchar('\\n'); after the second fflush() . 在第二个fflush() (I added void to int main(void) to avoid compilation warnings (errors) with my default compilation options.) (我在int main(void)添加了void ,以避免使用默认的编译选项进行编译警告(错误)。)

Osiris JL: make bs97 && bs97
    gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes bs97.c -o bs97
12345
Osiris JL: 

This time, the 4 and the 5 are still visible. 这次, 45仍然可见。

Simply using backspace does not erase the content that was previously there; 仅仅使用退格键并不会擦除以前存在的内容。 it positions the write position on screen back one place, that's all. 它将写位置放在屏幕后方一个位置,仅此而已。 If you want to erase what was there, you need to output printf("\\b \\b\\b \\b") to go back, output a space, and go back again — repeated twice. 如果要擦除其中的内容,则需要输出printf("\\b \\b\\b \\b")以返回,输出空格并再次返回-重复两次。 Or you could use printf("\\b\\b ") , but that would leave the write position after the two spaces; 或者,您可以使用printf("\\b\\b ") ,但这将在两个空格之后保留写位置。 or you could use printf("\\b\\b \\b\\b") to leave the write position after the 3 . 或者您可以使用printf("\\b\\b \\b\\b")3之后离开写入位置。 And there are other variations on this theme. 这个主题还有其他变化。

With the second program with the sleep, I get similar behaviour, except that the 12345 is on display while the program sleeps. 在第二个程序进入睡眠状态后,我会得到类似的行为,除了在程序进入睡眠状态时显示12345

I'm testing on a Mac running macOS 10.14 Mojave, using a home-built GCC 8.2.0 or the clang compiler from XCode 10.0. 我正在使用自制的GCC 8.2.0或XCode 10.0的clang编译器在运行macOS 10.14 Mojave的Mac上进行测试。

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

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