2017-07-02 61 views
0

有人可以解釋或指向我解釋了爲什麼在第一印刷行下面的代碼片段包括整個單詞hello的參考,而在第二個它是由只有字母he?我認爲退格轉義字符會刪除最後三個字母,而不考慮換行符。我已閱讀關於printf的GNU文檔,但無法找到任何關於點的信息。的處理B在模板字符串的printf用C

int main(void) 
{ 
    printf("hello\b\b\b\n");   
    return 0; 
} 



int main(void) 
{ 
    printf("hello\b\b\b"); 
    return 0; 
} 

回答

1

這不是真的關於C或printf的問題。在每種情況下,代碼都完全按照它的說法進行操作:在第一個示例中,它輸出9個字符h e l l o \b \b \b \n,在第二個示例中同樣輸出8個字符。如果您將標準輸出寫入到文件所包含的文件中。但是,如果你寫信給終端,你的終端可能會通過退格處理\b,所以你的問題真的是關於你的終端。你還沒有說你使用的是什麼終端。爲退格鍵的行爲

一種常見的方式是通過移動光標一個位置離開,但實際上沒有刪除在該位置的字符。下一個字符輸出將被寫在它上面。

在你的第一個例子中,你將光標移動回第一l,但你從來不寫在它或任何其他字符任何東西。然後\n不會更改屏幕上的任何字符,只是將光標移動到下一行。所以你仍然可以在上一行看到hello

在第二個示例中,當您的程序終止光標留在第一l。因此下一個將輸出寫入終端的程序將會寫入該字符(除非下一個程序的第一次寫入是\n或類似的東西)。下一個程序可能是你的shell,所以shell提示符中的字符可能會覆蓋​​,所以你看不到它們。

3

兩個關鍵的事情要記住:

  1. 輸出到控制檯當您使用printf()不會立即呈現:輸出緩衝。兩種方法可以立即(同步)刷新輸出緩衝區到控制檯是經由printf("\n")打印一個新行,或通過手動fflush(stdout)刷新緩衝區。
  2. 如果使用\b轉義序列,你會移動光標一個「空格」後/左,但打印一個換行符不一定會清除行的其餘部分。如果您要手動在舊的字符上打印新字符(即printf("Hello\b\b\b \n")),則輸出將更像您所期望的。

asciicast

Additionally, if you want to do some advanced command-line menus, graphics, etc, you'll need to use something like libncurses.

最後,下面的例子可以幫助提供有關涉及您的問題的通常行爲更好的主意。

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

#define DELAY (2) /* seconds */ 

int main(void) 
{ 

    printf("Example DELAY:\n"); 
    printf("------------------------------------------------------------------------\n"); 
    printf("hello\b\b\b\n"); 
    sleep(DELAY); 
    printf("\n\n"); 

    printf("Example 2:\n"); 
    printf("------------------------------------------------------------------------\n"); 
    printf("hello\b\b\b"); 
    sleep(DELAY); 
    printf("..."); 
    sleep(DELAY); 
    fflush(stdout); 
    sleep(DELAY); 
    printf("\n\n"); 

    printf("Example 3:\n"); 
    printf("------------------------------------------------------------------------\n"); 
    fflush(stdout); 
    printf("hello\b\b\b"); 
    fflush(stdout); 
    sleep(DELAY); 
    printf("..."); 
    sleep(DELAY); 
    fflush(stdout); 
    sleep(DELAY); 
    printf("\n\n"); 

    return 0; 
} 
+0

優秀的例子。一個快速的後續問題:爲什麼'#define DELAY(2)'語句中的大括號? – BruceM

+0

@BruceM在這個例子中,這太過矯枉過正,但它是爲了避免某些情況下宏不像你期望的那樣擴展。類似於多行宏通常包含在'do {...} while(0)'語句中。如果你看看PC-Lint,MISRA標準等,你會發現這種編碼風格的更多信息。 – DevNull