Sourav Yadav
Sourav Yadav

Reputation: 1

How can I take user input in Zig for this Fibonacci Series Generator

const std = @import("std");
const stdout = std.io.getStdOut().writer();
const print = std.debug.print;

pub fn fibonacci(n: i32) i32 {
    if (n <= 1) {
        return n;
    }

    return fibonacci(n - 1) + fibonacci(n - 2);
}

pub fn main() !void {
    var num: i32 = 15;
    var i: i31 = 1;

    var buf: [10]i32 = undefined;

    const stdin = std.io.getStdIn().reader();

    try stdout.print("enter a number: ", .{});

    if (try stdin.readUntilDelimiterOrEof(buf[0..], '\n')) |user_input| {
        num = std.fmt.parseInt(i32, user_input, 10);
    } else {
        num = @as(i32, 0);
    }

    // creating a loop
    while (i <= num) {
        print("{} ", .{fibonacci(i)});

        i += 1;
    }
}

It is the code I wrote to take user input for the number of terms to print the Fibonacci Series

and I get this following error:

> zig build-exe fibonacci.zig
fibonacci.zig:23:46: error: expected type '[]u8', found '*[10]i32'
    if (try stdin.readUntilDelimiterOrEof(buf[0..], '\n')) |user_input| {
                                          ~~~^~~~~
fibonacci.zig:23:46: note: pointer type child 'i32' cannot cast into pointer type child 'u8'
fibonacci.zig:23:46: note: unsigned 8-bit int cannot represent all possible signed 32-bit values
/home/alex/program/ziglang/lib/std/io.zig:187:18: note: parameter type declared here
            buf: []u8,
                 ^~~~
referenced by:
    posixCallMainAndExit: /home/alex/program/ziglang/lib/std/start.zig:617:37
    _start: /home/alex/program/ziglang/lib/std/start.zig:424:40
    3 reference(s) hidden; use '-freference-trace=5' to see all references
                                                                           

but I am unable to take user input normally like I can in C using the scanf() function.

Is there a better way to take input from user in Zig

I tried using the heap page_allocator instead of buff[] but still it showed some error

Upvotes: 0

Views: 106

Answers (1)

xiheyaoling
xiheyaoling

Reputation: 1

First, the buf parameter of this function requires a []u8 type, but your code has: var buf: [10]i32 = undefined;

After that, if you are using Windows, you will encounter another issue — Windows uses "\r\n" as the line ending, instead of just "\n". Therefore, you need to check for and remove the trailing "\r", or you will get an error: InvalidCharacter.

The final code is like this:

var buf: [32]u8 = undefined;
if (try stdin.readUntilDelimiterOrEof(buf[0..], '\n')) |user_input| {
    if (@import("builtin").os.tag == .windows) {
        const new_buf = std.mem.trimRight(u8, user_input, "\r");
        num = try std.fmt.parseInt(i32, new_buf, 10);
    } else {
        num = try std.fmt.parseInt(i32, user_input, 10);
    }
    print("num is:{}\n", .{num});
} else {
    num = @as(i32, 0);
}

Zig's official documentation provides examples of how to use the reader. You can check it out.

I'm not a native English speaker, so feel free to point out any grammatical mistakes.

Upvotes: 0

Related Questions