如何使用运行时格式字符串在 Zig 中格式化字符串

问题描述 投票:0回答:1

我对学习 Zig 完全是菜鸟,所以我的问题可能很天真。

我正在尝试使用标准库中的字符串格式化函数(例如

std.fmt.allocPrint()

)在代码中创建各种字符串

当我一次只处理一个字符串时,它是有效的,但是当我决定将其抽象为一个函数时,编译器告诉我

allocPrint
的格式字符串是
comptime

我找不到任何方法来使用运行时格式字符串来实现同样的事情。

是否有一种完全不同的方法,涉及不使用

std.fmt
,或者我是否因为是初学者而错过了一些基本的东西?

string-formatting zig
1个回答
0
投票

Zig 的打印函数需要编译时已知的格式字符串。如果需要动态字符串,可以使用C的printf。

这是我在版本 0.12.0-dev.2296+46d592e48 上运行的东西。

const c = @cImport({
    @cInclude("stdio.h");
});

const std = @import("std");

// Returns a null-terminated heap-allocated string, usable in C, containing the phrase "hi " repeated numHis type.
const hi = "hi ";
fn getHis(allocator: std.mem.Allocator, numHis: usize) ![*:0]u8 {
    const total_len = numHis * hi.len;
    // allocSentinel ensures it ends with a \0.
    const s = try allocator.allocSentinel(u8, total_len, 0);
    var i: usize = 0;
    while (i < total_len) : (i += hi.len) {
        // repeatedly copy the phrase into the allocated memory.
        std.mem.copyForwards(u8, s[i .. i + hi.len], hi);
    }
    return s;
}

// Returns a null-terminated heap-allocated string, usable in C, containing some border chars and the phrase "%s", which can be passed as a format string to c's printf.
const strInsert = "\n%s\n";
fn getBorderedFormatString(allocator: std.mem.Allocator, borderChar: u8) ![*:0]u8 {
    const total_len: usize = 20 + strInsert.len + 2; // add 2 for leading and trailing newline
    const s = try allocator.allocSentinel(u8, total_len, 0);
    var i: usize = 0;
    s[i] = '\n';
    i += 1;
    while (i < 11) : (i += 1) {
        s[i] = borderChar;
    }
    std.mem.copyForwards(u8, s[i .. i + strInsert.len], strInsert);
    i += strInsert.len;
    while (i < total_len - 1) : (i += 1) {
        s[i] = borderChar;
    }
    s[i] = '\n';
    return s;
}

test "dynamic_phrase" {
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    const allocator = arena.allocator();
    const s = try getHis(allocator, 30);
    const f = try getBorderedFormatString(allocator, '+');
    _ = c.printf(f, s);
}
© www.soinside.com 2019 - 2024. All rights reserved.