429 words
2 minutes
String_View_zig

link#


Zig Code#

// main.zig
const std = @import("std");
const Io = std.Io;

const string_view_zig = @import("string_view_zig");

const StringView = struct {
    data: [*]const u8,
    count: usize,

    // String_View sv(const char *cstr)
    pub fn sv(cstr: [*:0]const u8) StringView {
        return StringView{
            .data = cstr,
            .count = std.mem.len(cstr),
        };
    }

    pub fn chopLeft(self: *StringView, n: usize) void {
        var k = n;
        if (k > self.count) {
            k = self.count;
        }

        self.count -= k;
        self.data += k;
    }

    pub fn chopRight(self: *StringView, n: usize) void {
        var k = n;
        if (k > self.count) {
            k = self.count;
        }

        self.count -= k;
    }
};

pub fn main(init: std.process.Init) !void {
    try std.Io.File.stdout().writeStreamingAll(init.io, "StringView zig lang (ver0.16.0-dev.2984+cb7d2b056)\n\n\n");

    var s = StringView.sv("Hello, World");

    s.chopRight(3);
    s.chopLeft(2);

    std.debug.print("{s}\n", .{s.data[0..s.count]});
}
  • result
$ zig build run

StringView zig lang (ver0.16.0-dev.2984+cb7d2b056)


llo, Wo

zig코드 자세히 분석#

pointer to a null-terminated C string.#

  • In Zig,
cstr: [*:0]const u8
  • means pointer to a null-terminated C string.

  • I used this type because your original C code takes const char *, and in C that usually means a 0-terminated string.

  • Let’s break it down.

1. Your C code#

String_View sv(const char *cstr) {
    return (String_View){
        .data = cstr,
        .count = strlen(cstr),
    };
}
  • Here:
// main.c
const char *cstr
  • means:

    • pointer to char
    • string must end with '\0'
    • required by strlen
  • So Zig must use a type that guarantees null-termination.

2. Meaning of [ *:0 ]const u8 in Zig#

[*:0]const u8
  • Breakdown:
PartMeaning
u8byte (same as char)
constread-only
[*]pointer to many items
:0sentinel value = 0 (null terminator)
  • So:
[*:0]const u8
  • means

pointer to many bytes, terminated by 0

  • Exactly like:
// main.c
const char *
  • but safer, because Zig knows there is a terminator.

3. Why not []const u8 ?#

  • Because this:
[]const u8
  • is a slice, not a C string.

  • Slice already has length:

ptr + len
  • So you don’t need strlen.

  • Your C code uses strlen, so we need null-terminated string.

4. Why std.mem.len(cstr) works#

  • std.mem.len expects a sentinel pointer:
std.mem.len(cstr)
  • Works only if type is:
[*:0]const u8
  • because it scans until 0.

  • Same as:

// main.c
strlen(cstr)

5. If we used wrong type (example)#

  • ❌ Wrong:
pub fn sv(cstr: []const u8) StringView
  • Then this fails:
std.mem.len(cstr) // error
  • because slice already has length.

6. Summary#

Zig typeMeaningC equivalent
[*:0]const u8null-terminated pointerconst char *
[]const u8slice (ptr + len)pointer + length
[*]const u8pointer without lengthraw pointer
  • So I used:
// main.zig
cstr: [*:0]const u8
  • because your C code uses:
// main.c
const char * + strlen
  • which requires a null-terminated string.
String_View_zig
https://younghakim7.github.io/blog/posts/string_view_zig/
Author
YoungHa
Published at
2026-03-27