# Best practices & idioms for getting user terminal input?

**URL:** <https://ziggit.dev/t/best-practices-idioms-for-getting-user-terminal-input/4474>\
**Category:** Help\
**Tags:** language, memory-management, comptime\
**Created:** [May 28, 2024, 7:49am UTC](https://ziggit.dev/t/best-practices-idioms-for-getting-user-terminal-input/4474 "2024-05-28T07:49:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![heartbeast42](https://ziggit.dev/letter_avatar_proxy/v4/letter/h/67e7ee/32.png) [@heartbeast42](https://ziggit.dev/u/heartbeast42)\
**Post date:** [May 28, 2024, 7:49am UTC](https://ziggit.dev/t/best-practices-idioms-for-getting-user-terminal-input/4474/1 "2024-05-28T07:49:41Z")

</div>

Hey y’all!

I’m trying to take user input from the terminal and I’m just wondering if there are good idioms for doing this in a robust & more flexible way…

Context:

- I’ve been programming for about a decade and I’m quite comfortable working in higher level languages such as Python, Java, JS etc…
- I’m new to systems programming in general but I’ve been dabbling in C and Rust on and off for a few years.
- I’ve been learning Zig for just a few weeks now but already really like it & things are coming together.
- – I’m still trying to grasp the idioms and concepts of manual memory management, in particular I feel quite shaky on the inner workings of the heap and memory pages and allocators in general.

What I’m focusing on here is trying to reconcile several examples I’ve seen online from the official docs and other random sources concerning **needing to assign an input to a `[]u8`** where the **size** of the `[]u8` is **known at compile time**.

```zig

const stdin = std.io.getStdIn().reader();
var input: [100]u8 = undefined; // <- this is the line my post is about
    // how do I do this with []u8 instead of [100]u8
    // or how can I dynamically size this variable

std.debug.print("enter something :) {s}", .{""});
_ = try stdin.readUntilDelimiter(&input, '\n');
std.debug.print("The user entered: {s}\n", .{input});

```

What I’m wondering is…

1. Is it possible to assign a result of a reader to a variable who’s size is determined by the size of the string deposited by the reader? In other words, to dynamically size the variable being mutated by the reader.

2. If it is possible, how and what considerations should I be making and are there good idioms / best practices / examples for how I can implement a dynamically sized input variable.

3. Is it a bad idea? If so, why? Is there a strong case to not do things this way and just commit to a fixed size and try to anticipate the size of the input up front?

Please feel free to include any recommend reading that may help me understand this, especially where memory management is concerned.

Thanks in advance! 🤓 ❤ ⚡

---

<div class="post-metadata">

**Author:** ![dimdin](https://ziggit.dev/user_avatar/ziggit.dev/dimdin/32/1457_2.png) [@dimdin](https://ziggit.dev/u/dimdin)\
**Post date:** [May 28, 2024, 10:39am UTC](https://ziggit.dev/t/best-practices-idioms-for-getting-user-terminal-input/4474/2 "2024-05-28T10:39:19Z")

</div>

Hi @heartbeast42 Welcome to ziggit 🙂

> [@heartbeast42](#):
>
> Is it possible to assign a result of a reader to a variable who’s size is determined by the size of the string deposited by the reader?

Yes, it is possible.

> [@heartbeast42](#):
>
> how I can implement a dynamically sized input variable

You don’t preallocate a buffer because the size is not known before calling the reading function.  
The reading function must return a newly allocated buffer that fits the entire line.

> [@heartbeast42](#):
>
> Is it a bad idea?

No, it is not. Usually a fixed buffer can be used when there is an upper bound for reading, or it is not necessary to have the entire line for processing.

* * *

The reading function does not know the length of the line, it starts by allocating a fixed buffer (for example of 100 bytes) and reading until either the buffer is full or there is a newline. When the buffer is full it resizes the buffer by expanding it (for example to its double size 200, 400, 800, etc bytes). When the reading or the line is done it returns the allocated buffer with its size as a slice and the caller is responsible for freeing the memory.

The main requirement is to have an [allocator](https://ziglang.org/documentation/master/std/#std.mem.Allocator), and the allocator job is to [alloc](https://ziglang.org/documentation/master/std/#std.mem.Allocator.alloc)ate, [realloc](https://ziglang.org/documentation/master/std/#std.mem.Allocator.realloc)ate and [free](https://ziglang.org/documentation/master/std/#std.mem.Allocator.free) memory.
