#How to get standard input from cli ?

1 messages ยท Page 1 of 1 (latest)

strong jetty
#

Two kinds of inputs:

  • arguments
  • files (stdin is a file for this purposes)
#

Which are you interested

obsidian acorn
#

natural numbers

strong jetty
#

The we have std.process.argsIterator

#

or std.process.args

#

both work fine

#

But you have to parse the elements

#

since the arguments are strings

obsidian acorn
#

do i need some kind of heap allocation for this. dont mind i never tried low level languages

strong jetty
#

In linux? no, in windows? yes

#

Generally languages do this for you, but zig is different regarding this, and ask you to explicitly to allocate

obsidian acorn
strong jetty
obsidian acorn
strong jetty
obsidian acorn
#

but i am on linux

#

๐Ÿ˜‚

#

whats the deal ? not on linux but on windows

strong jetty
#

Windows need an allocation for it

#

linux doesn't

#

is just OS Weirdness

obsidian acorn
#

for standard input oh okay

strong jetty
#

either way you can just pass an allocator and forget about it

#
    var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    defer arena.deinit();
    var allocator = arena.allocator();
    var args = try std.process.argsAlloc(allocator);
    defer allocator.free(args);

This is my current code for a tool I use, this returns me a [][:0]u8 (A slice of strings of bytes)

#

so I can work with each string however I like

But there is also:
std.process.argsWithAllocator(allocator);
Which returns an iterator

#
    var argsit = try std.process.argsWithAllocator(allocator);
    defer argsit.deinit();
    while (argsit.next()) |arg| {
      // Use the args
    }
obsidian acorn
strong jetty
#

all frees are """"no-operation"""" (there is actual some, but let's ignore it) and it frees all memory at the end

#

I use it because it's a short lived program in my case and I did not care

#
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
var ally = gpa.allocator();

This right here is the general purposed one, that detect if you have a memory leak

obsidian acorn
#

does this have something to do with block scope? like scope gone variable freed

obsidian acorn
strong jetty
#

defer just means: "At the end of this block, execute this"

strong jetty
obsidian acorn
#

zig seems interesting

#

btw thanks mate

strong jetty
#

generally whatever you init, you deinit, whatever you create you destroy and whatever you alloc you free

obsidian acorn
#
while (argsit.next()) |arg| {
      // Use the args
``` what does this `| arg |` implies
strong jetty
#

argsit.next() returns a ?[:0]const u8
? means the following type is "nullable" (can be asigned null)
while accept nullable values and boolean values
nullable values needs the syntax I wrote above and doing so, it "Captures" the value when not null, and asign it to arg

#

This works in all flow control that accept truth values (well, that is just if and while ig)

if(argsit.next()) |arg| {} 
#

The equivalent would be:

var arg = argsit.next();
while(arg != null) {
     var arg_payload = arg.?;
     arg = argsit.next();
// Use the payload

}
#

or well the more succint syntax

obsidian acorn
#

ohk

strong jetty
#
var arg = argsit.next();
while(arg != null) : (arg = argsit.next()) {
     var arg_payload = arg.?;
// Use the payload

}
obsidian acorn
#

and how to make it wait to take the input

strong jetty
#

Oh ok, then you don't need arguments

#

you need standard input ๐Ÿ˜„

#

Different concepts ๐Ÿ˜„

obsidian acorn
#

๐Ÿ˜‚

#

are arguements different?

strong jetty
#

Here is how you would use this:

my_program 10 20
obsidian acorn
#

i need to build it okay

strong jetty
#

stdin still needs to build it, just that the program keeps waiting for something to read

obsidian acorn
#

yeah worked

#

got 2 args

#

is this a array var args = try std.process.argsAlloc(allocator);

#

i can get index of it ?

#

[][:0]u8

#

it shows

#

idk what that

strong jetty
#

yeah sure

#

is an "array" of sorts

#

I say of sorts because it's really a ptr you can access the offset of, but dw about details, know you have a .len field tellin you how long it is, and you can access via index with args[0], which will access the first argument

#

(Which is the program name btw)

obsidian acorn
obsidian acorn
#

or pointer to array

strong jetty
#

to be exact:
[][:0]const u8 means: "A slice (ptr + len) that holds slices (ptr + len) with a 0 terminated separation (sentinel) of a bunch of bytes"

#

the ptr is a multiptr which implies multiple elements on contigous memory

#

which I guess COULD be defined as an array

#

In zig it would be correct at least, since arrays are contigous memory as value

#

in C is a bit more nebolous

obsidian acorn
#

Ah now i get it

obsidian acorn
#

@strong jetty when i access its index

#

it gives me [:0]u8

#

how can i parse this to u8

strong jetty
#

u8 would be a char

#

well a byte

#

You need to parse it to whatever the type you need

obsidian acorn
#

char?

#

byte?

strong jetty
#

A string of 8 bit values (which nowadays are chars)

obsidian acorn
strong jetty
#

Depends on what you need

#

"Hello, this is a [:0]const u8"

obsidian acorn
#

Oh

#

how will i parse it then?

strong jetty
#

Depends on what do you need

#

There is no single answe

obsidian acorn
livid jacinth
obsidian acorn
#

and [:0]what does this :0 mean here

strong jetty
#

Sentinel, it means the last character is the end and is marked as the end by 0

#

"If you could see, at the end of this string there is a 0, like an actual byte 0"

#

If you would see the underlying bytes, the last char is a 0

obsidian acorn
#

to end it?

strong jetty
#

so, how you know how long is a string?

obsidian acorn
#

hmm

livid jacinth
#

for instance, when you interface with a C library, when it requests a string it usually wants a [*:0]const u8

#

something that terminates in a \0

strong jetty
#

@obsidian acorn so, since ptrs have no len attached, and actually goign arround with a len is wasteful (specially for the time C was written), 0 was decided as the "Here lies the end of the string"

strong jetty
#

Having a len is wasteful in memory, relying on the 0 to end stuff basically means computational cycles getting to the end

obsidian acorn
#

๐Ÿ‘

#

so uh what do i do to parse [:0]u8 to u8

#

like i checked it gives some { 49, 48, 48 } when i type 100 in console

strong jetty
#

Here is the deal

#

let's call things by the names and not the types: since a valid answer could be just take index 0 hahaha

#

In this case is: "How do I get a string to a value in between 0 and 255"
In this case std.fmt.parseInt is your friend

#

or doing it yourself

#
var my_u8 = try std.fmt.parseInt(u8,args[1],10);

or the manual method

var result = 0;
for(args[1], 0..) |val,i| {
result += (val - 48)  * std.math.pow(u8, 10, args.len - i);
}
livid jacinth
#

shouldn't you do val - 0x30 in this case?

strong jetty
#

This uses the fact that the nubers chars is from [48-57]

obsidian acorn
#

Ok

obsidian acorn
#

like segfaults and etc

strong jetty
#

Well, zig provides a stacktrace

#

But you can use code-lldb, lldb, gdb, windbg (windows only) etc.

obsidian acorn
#

0kay

obsidian acorn
#

Block is a struct

strong jetty
#

You are initiing with the wrong syntax

#

cannot see the code

#

๐Ÿ˜„

obsidian acorn
# strong jetty cannot see the code
const std = @import("std");
const print = std.io.getStdOut().writer().print;

const Block = struct { user: block_state, filled: bool, index: i8 };
const block_state = enum { none, x, o };
pub fn main() !void {
    var allocator = std.heap.page_allocator;
    var board = std.ArrayList(Block).init(allocator);
    defer board.deinit();
    for (0..9, 0..) |_, index| {
        board.append(Block{ block_state.none, false, index });
    }
    try print("{any}", .{board});
}```
#

this is the whole thing

strong jetty
#

you are skipping the fields

#

so it guesses array init

obsidian acorn
strong jetty
#
Block {.user = .none, .filled = false, .index = index};
obsidian acorn
strong jetty
#

yea

#

.field = val

obsidian acorn
#

ahh okay

strong jetty
#

.{ .field = val} works too

obsidian acorn
#

in rust it was different mb

strong jetty
#

(Y)

obsidian acorn
#

index

#

coming from the for loop

#

its gives usize

#

nvm i just changed u8 to usize

obsidian acorn
#

@strong jetty i saw two parameters in a function with

#

&

#

and *

#

what does these mean

#
fn handleConnection(allocator: *std.mem.Allocator, conn: *std.net.StreamServer.Connection) ```
#

here

#

and js try handleConnection(allocator, &conn);

#

here

#

are those references?

strong jetty
#

* means is a ptr to something
& is taking the address of something (getting the ptr)

#

If you wanna see them like that ,sure

obsidian acorn
#

what does taking address mean in a function

strong jetty
#

things are memory, using & gets where they are in memory

obsidian acorn
#

&conn = address of conn

#

why we need to pass pointers ?

#

what is different in passing a variable and a pointer

#

i guess pointer also gives us the value stored there

#

in rust it was some ownership thing

#

whats the matter in zig?

#

i know my words dont any make sense :\

fresh pollen
#

a pointer points to some value in memory

obsidian acorn
dry frost
#

you can modify the original value if you pass by pointer

fresh pollen
#

if you just pass a value to a function and then try and change that, nothing will happen

#

well, you'll get a compile error

obsidian acorn
#

Oh

fresh pollen
#

because you're changing a copy of the value

dry frost
#

so:

fn foo(p: *i32) void {p.* = 69}

test "foo sets integer to 69" {
    var x: i32 = 0;
    foo(&x);
    try std.testing.expectEqual(@as(i32, 69), x);
}
obsidian acorn
#

hmm makes sense

#

p.* = 69 what does this does

#

it seems it sets it to 69 but

#

what p.* means

dry frost
#

.* means "dereference this pointer", "get the thing this pointer points to"

obsidian acorn
#

Oh

#

foo(&x);

#

foo needs a pointer

dry frost
#

the & means "get a pointer to this thing"

obsidian acorn
#

Oh

#

get a pointer

obsidian acorn
dry frost
#

*T means "pointer to this type"

#

e.g. *i32 means pointer to i32

#

and so on

obsidian acorn
#

Ohkay

#

so to get a pointer to smthg we need to use &<var>

#

got it

dry frost
#

maybe this helps (it's C syntax, I should update that)

obsidian acorn
#

we can have pointers to pointers

dry frost
#

yes

obsidian acorn
#

lol

dry frost
#

**i32

obsidian acorn
#

okay thanks lol

#

the best ever support server i have seen

strong jetty
#

We got helpful people ๐Ÿ˜›

obsidian acorn
#

@strong jetty whats u31

#
(u31)
Copied from Options on init.```
strong jetty
#

aribitrary int sizes in zig

#

u31 is 31 bits numbers

#

Which generally is u32 ignoring 1 bit

obsidian acorn
#

is there any way to listen on a port

#

i figured that net.ServerStream can do that

#

but i dont know how to use it

edgy hill
dry frost
obsidian acorn
#

@strong jetty where can i get explaination of how to use standard library modules like net etc

strong jetty
#

Things you learn reading the docs

obsidian acorn
dry frost
livid jacinth
#

if autodocs doesn't cut it you should read the source code/examples

dry frost
#

If something isn't clear, please make a PR to add doc comments after reading the code.

livid jacinth
#

tests are useful too

strong jetty
#

I need to update that, fuck lel

#

Why did I say yes lel

#

But yes, should work

obsidian acorn
#

@strong jetty

#

i have come across this error many times

#

what does it mean

#

src/main.zig:11:36: error: array literal requires address-of operator (&) to coerce to slice type '[]const u8'

#
try conn.stream.write([4]u8{ 0, 12, 3, 23 });
strong jetty
#

Arrays are not slices

#

and cannot coerce to slices

#

but the address to an array is possible to make a slice

obsidian acorn
#

its asks for an array

#
fn write(self: Stream, buffer: []const u8) WriteError!usize
TODO in evented I/O mode, this implementation incorrectly uses the event loop's file system thread instead of non-blocking. It needs to be reworked to properly use non-blocking I/O.
strong jetty
#

It ask for a slice

#

not an array

obsidian acorn
#

oh strings?

#

slices are strings right?

#

like "test"

strong jetty
#

Slices are not strings, but strings can be slices

strong jetty
#

Read the langref a bit more

obsidian acorn
#

passed a string

#

so i thought slices are strings lol

#

my bad

obsidian acorn
obsidian acorn
#

@strong jetty what does comptime_int means?

dry frost
#

its an int

#

but only at comptime