Windows 当输出与 window 的宽度匹配时,控制台 (conhost) 丢弃新行

Windows Console (conhost) discards newline when output matches witdth of the window

我在 Windows 上有一个 C++ 应用程序,它记录到标准输出(通过使用 WriteConsole 的 Win32 api)。每个日志行都包含一些文本和一个尾随的换行符。问题是:

当日志文本的宽度(不包括换行符)与控制台的宽度匹配时window,换行符将被丢弃。

看这个例子:

有 3 条日志消息:

如果我调整 window 的大小,会发生以下情况:

第二行和第三行合并为一行,尽管它们之间打印了一个换行符。我怀疑 windows 为了聪明,在第二条消息之后丢弃了换行符,因为它会在视觉上导致第二条消息和第三条消息之间出现间隙(换行的新行 + 我的换行符) .对于那个控制台宽度来说,这一切都很好,但是当我调整大小时,一切都坏了。

Strive Sun - MSFT 在他们的回答中指出,这种行为似乎是由于设置了 ENABLE_VIRTUAL_TERMINAL_PROCESSING 标志而发生的。禁用它可以解决问题。我使用这个标志来启用不同颜色的输出,所以想找到一些方法来修复换行符而不丢失彩色输出。

有什么方法可以告诉 Windows 不要那样做(不禁用 ENABLE_VIRTUAL_TERMINAL_PROCESSING 不丢失颜色)?

有什么方法可以告诉 Windows 不要那样做吗?

经过一番调试,发现在控制台去掉ENABLE_VIRTUAL_TERMINAL_PROCESSING 样式后就不会出现这个问题了

像这样,

DWORD lp;
HANDLE std_out = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleMode(std_out, &lp);
SetConsoleMode(std_out, lp &~ENABLE_VIRTUAL_TERMINAL_PROCESSING );
...

已更新:

int main()
{
    DWORD lp;
    HANDLE std_out = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleMode(std_out, &lp);
    SetConsoleMode(std_out, lp & ~ENABLE_VIRTUAL_TERMINAL_PROCESSING);

    SetConsoleTextAttribute(std_out, FOREGROUND_RED);
    DWORD written;
    char str1[] = "aaaaaa\n";
    char str2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\r\ndddddd";
    //    char str2[] = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n";
    char str3[] = "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n";
    int len = strlen(str2);
    WriteConsoleA(std_out, str1, strlen(str1), &written, NULL);
    SetConsoleTextAttribute(std_out, FOREGROUND_INTENSITY);
    WriteConsoleA(std_out, str2, strlen(str2), &written, NULL);
    SetConsoleTextAttribute(std_out, FOREGROUND_INTENSITY | FOREGROUND_GREEN); 
    WriteConsoleA(std_out, str3, strlen(str3), &written, NULL);
    system("pause");
    return 0;
}

更多颜色请参考:C++ Win32 Console Color

我发现,如果想继续使用 ANSI 转义码并且不想因换行而出现奇怪的错误,将其传递给 ConsoleMode 就足够了:

auto h = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleMode(h, ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING);