The Zig standard library contains the function std.fmt.allocPrint
which takes in an allocator, prints to a buffer allocated with said allocator, and returns the result, much like a dynamic sprintf
.
For my particular use-case, I need to concatenate multiple strings together after having printed to them. The only solution that I see, using allocPrint
, is to first print to some allocated memory and then copy the bytes over to an ArrayList
, which seems redundant.
Ideally, the standard library would include a function that allows one to print directly to an ArrayList
, like the following:
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const allocator = gpa.allocator();
var list = std.ArrayList(u8).init(allocator);
defer list.deinit();
const values = [_]f64{ 5.6, 123.4, 19.6, 18.4 };
for (values) |value| {
try std.fmt.allocPrintToArrayList(list, "{e} ", .{value}); // Does not work
}
_ = list.pop();
// Ideally `list.items` would include the `values` delimited by spaces
}
Is there a way of doing what I need in Zig? For example, maybe I could use ArrayList
as an allocator so it can be, in turn, used with the allocPrint
API.
Printing to a Single String
I misunderstood the problem statement at first: I thought that OP wanted to collect strings in an
ArrayList
, but it seems that OP wants to create a single string by printing values followed by delimiters. The original solution is at the end of this answer.ArrayList
has awriter
method which appends to the end of a list. You can combine that with a bit of logic to print delimiters to arrive at the desired result.The Original Answer: Creating a List of Strings
You can use
ArrayList.append
to append the result of callingallocPrint
to theArrayList
sinceallocPrint
returns a slice of the bytes which were printed. SinceallocPrint
makes an allocation each time it is called these will also need to be freed.The
ArrayList
will also need to hold[]u8
types instead ofu8
types.