Skip to content

stdout sink produces extra carriage returns on Windows #1675

@chris-t-w

Description

@chris-t-w

Given the following example:

#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "spdlog/sinks/stdout_color_sinks.h"

int main()
{
    std::shared_ptr<spdlog::logger> logger1 = spdlog::stdout_logger_st("one");
    logger1->set_pattern("%v");
    logger1->info("hello");

    std::shared_ptr<spdlog::logger> logger2 = spdlog::stdout_color_st("two");
    logger2->set_pattern("%v");
    logger2->info("world");

    return 0;
}

If we run this program on Windows and redirect the output to a file (example.exe > output.txt) and have a look at this output in a hex editor, we see the following:

68 65 6C 6C 6F 0D 0D 0A 77 6F 72 6C 64 0D 0A
h  e  l  l  o  \r \r \n w  o  r  l  d  \r \n

i.e. "hello\r\r\nworld\r\n" - notice the additional carriage return after "hello".

I believe the first example can be explained because:

  1. stdout_logger_st uses fwrite to write to the stdout handle
  2. The formatter automatically appends \r\n by default
  3. stdout is opened in text mode according to: https://docs.microsoft.com/en-us/cpp/c-runtime-library/text-and-binary-mode-file-i-o ("The stdin, stdout, and stderr streams always open in text mode by default")
  4. Streams opened in text mode will automatically replace \n with \r\n according to: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/fwrite ("If stream is opened in text mode, each line feed is replaced with a carriage return-line feed pair")

This is a problem because some programs interpret the \r\r\n as two lines, resulting in all of the logs appearing with extra blank lines between them.

The only thing I can't explain is why the problem doesn't seem to happen with the color sink, which you can see from the output above produces the correct "world\r\n".

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions