Categories
Tags
algorithms APIT Arc arm assembly asynchronous base64 BitHacks Blogging box c clang-format client cmake compiler concat concurrency const_fn contravariant cos covariant cpp Customization cybersecurity DataStructure db debugging Demo deserialization discrete doc DP dtruss Dynamic Example FFI flat_map format FP fsanitize Functional functions futures Fuwari GATs gccrs generics gitignore glibc GUI hacking hashmap haskell heap interop invariant iterator join justfile kernel LaTeX leak LFU linux lto MachineLearning macOS Markdown math ML mmap nc OnceLock optimization OS panic parallels perf physics pin postgresql radare2 release reverse RPIT rust sanitizer science Science serialization server shift sin SmallProjects socket std strace String StringView strip strlen surrealdb SWAR swisstable synchronous tan toml traits triangulation UnsafeRust utf16 utf8 Video wsl x86_64 xilem zig
429 words
2 minutes
String_View_zig
link
C Strings are Terrible! | Tsoding | C의 String은 끔찍하다. ㅋ C String 정말 끔찍해! 자동 더빙 | Tsoding
같이 연관 되는 blog글
- These patterns prevent crashes, overflow, UB, or invalid memory access
- C & Rust로 구현한(StringView)
Zig Code
zig version (0.16.0-dev.2984+cb7d2b056)
// 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, Wozig코드 자세히 분석
pointer to a null-terminated C string.
- In Zig,
cstr: [*:0]const u8means 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 *cstrmeans:
- 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:
| Part | Meaning |
|---|---|
u8 | byte (same as char) |
const | read-only |
[*] | pointer to many items |
:0 | sentinel 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 u8is a slice, not a C string.
Slice already has length:
ptr + lenSo 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.lenexpects a sentinel pointer:
std.mem.len(cstr)- Works only if type is:
[*:0]const u8because 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 type | Meaning | C equivalent |
|---|---|---|
[*:0]const u8 | null-terminated pointer | const char * |
[]const u8 | slice (ptr + len) | pointer + length |
[*]const u8 | pointer without length | raw 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/