Convert []const u8 to [*:0]const u8

So I am writing a shell. I was following along to ratfactor’s blog post about creating it in Zig. However, I am working on implementing some builtins like cd to the shell. So I am taking in user input, and splitting it on whitespace with std.mem.splitSequence. It works great. The problem is it is in []const u8 format. I am using std.os.chdirZ to attempt to change directories. This takes [*.0]const u8. Being a beginner I have no idea how to swap between these two types. Any help would be massively appreciated.

Hello @jjuel, welcome to the forum.


  • [*:0]const u8 is a sentinel terminated pointer, a pointer to 0 terminated string of u8.
  • []const u8 is a slice, a pointer and a length.
  • [:0]const u8 is a 0 terminated sentinel slice, a pointer to 0 terminated string and a length.


  • To convert from a zero terminated pointer to a slice use: std.mem.span .
  • To convert from a 0 terminated sentinel slice to a zero terminated pointer call .ptr
// "Hello" is a zero terminated array of u8
const hello: [:0]const u8 = "Hello";
const ptr: [*:0]const u8 = hello.ptr;

@dimdin, I think we should make a Doc about this. I can get it started off of your post.

1 Like

@dimdin’s answer is more general, but since you’re working with paths, there are other options:

First, it’s unclear why you’re choosing chdirZ over chdir when you don’t already have a sentinel-terminated slice.

But if you really want to call chdirZ directly, you can use a stack-allocated buffer for the sentinel terminated slice instead of heap allocating. Using a stack allocated buffer is exactly what chdir does via toPosixPath:

where toPosixPath looks like this:


This is great knowledge. Thank you. Honestly, the reason I wasn’ t using chdir over chdirZ was just not reading of it. As it turns out I did have sentinel-terminated slice I just didn’t realize I had it until after asking these questions. Thank you again. I am still learning Zig and systems programming.

1 Like

Another thing to note that you dont need to construct paths generally in zig. You can instead tokenize the path and traverse the components directly with std.fs.Dir.openDir this is actually sometimes required because filesystems may have max path limit, also relying on MAX_PATH especially is fragile