I wanted to write fizzbuzz, but instead of just printing, store it in an array.
The problem is converting the numbers to strings. I first tried with bufPrint
, but It outputed white-space instead of a number. Then I tried out with allocPrint
, it compiles the app, but after entering the number crashes, with weird error messages in std/fmt
. I tried printing the output of allocPrint
, it outputs correctly, but I can't add it to the array.
After much more, I found out that the type that allocPrint
produces is a string of type []u8
, but my type is []const u8
. How can I turn the output of the function to []const u8
?
The askUser
function works correctly & produces a u64, the problem is not related to it. Also, what is the best or most common string type in zig?
code
const std = @import("std");
fn fizzBuzz(x: usize) !std.ArrayListAligned([]const u8, null) {
const allocator = std.heap.page_allocator;
var array = std.ArrayList([]const u8).init(allocator);
var i: usize = 0;
while (i != x) : (i = 1) {
const string = try std.fmt.allocPrint(allocator, "{d}", .{i 1});
defer allocator.free(string);
try array.append(if (((i 1) % 3 == 0) and ((i 1) % 5 == 0)) "FizzBuzz"
else if ((i 1) % 3 == 0) "Fizz"
else if ((i 1) % 5 == 0) "Buzz" else string);
}
return array;
}
pub fn main() !void {
const count = try askUser("! ");
var x = try fizzBuzz(@intCast(usize, count));
defer x.deinit();
defer std.debug.print("\n", .{});
for (x.items) |y| {
std.debug.print("{s} ", .{y});
}
}
CodePudding user response:
The std.ArrayList([]const u8)
doesn't take ownership of the strings you put into it. It only takes slices (which is a pointer length). So, when you deallocate the strings in the loop you invalidate the slices that you just added into the array list.
Simply removing defer allocator.free(string);
makes your program print a correct result.
How to convert
[]u8
to[]const u8
in Zig?
No need to do anything, the type coercion happens implicitly.