0

When using the buffered writer and reader, my output is sometimes incomplete or behaves strangely. This is seemingly caused by the string formatting of my final output message.

After following this tutorial I created the following code. It simply takes user input and returns a formatted message:

const std = @import("std");

pub fn main() !void {
    // Handle to the standard output
    const stdout = std.io.getStdOut();
    var bw = std.io.bufferedWriter(stdout.writer());
    const w = bw.writer();

    // Handle to the standard input
    const stdin = std.io.getStdIn();
    var br = std.io.bufferedReader(stdin.reader());
    var r = br.reader();

    // Initial prompt
    try w.print("What is your name?: ", .{});
    try bw.flush();

    var msg_buf: [64]u8 = undefined;
    var msg = try r.readUntilDelimiterOrEof(&msg_buf, '\n');

    if (msg) |m| {
        try w.print("Hello, {s}\n", .{m});
    }
    try bw.flush();
}

The program functions as expected:

What is your name?: Foo                                              
Hello, Foo

However, when I change the location of {s} in the 'if' statement like so:

try w.print("Hello, {s}!\n", .{m});

This happens:

What is your name?: foo                                              
!ello, foo

The same happens if i use any other character such as '.', or even ' ' (space). The first character is replaced by the character after the {s}. What am I doing wrong to cause this issue? I also notice that without '\n', no output occurs at all. try w.print("{s}", .{m}); will cause nothing to be returned after user input.

Placing the formatting at the beginning allows for output, but the input message is never displayed:

try w.print("{s}! So good to see you\n", .{m});

Result:

What is your name?: Foo                                              
! So good to see you  

I must be misusing the buffers somehow, and I'm sure this code could be improved to alleviate this issue. Any help or detailed documentation would be appreciated.

1 Answers1

2

From the problem you're seeing I assume you're using a Windows machine.

The reason for the weird behaviour with ! after the {s} comes from the fact that Windows uses \r\n as its line ending instead of the Unix \n. Your code correctly reads the \r as the last character of the input and when printing this special character makes the write "cursor" move to the beginning of the line, overwriting the text already present there.

You can avoid this problem by trimming the input string using for example the stdlib function std.mem.trim

Der_Teufel
  • 21
  • 1
  • 2