#process a string before returning it

1 messages · Page 1 of 1 (latest)

thin garden
#

can i do const mystr: [:0]u8 = wrapStr("Some long text 123 abc efg hij klm nop")

#

where wrapStr adds \n every few words

#
fn wrapStr(comptime string: []const u8) [:0]const u8 {
    comptime {
        var wrap = 20;
        var out: [string.len:0]u8 = undefined;

        for (0..out.len) |i| {
            if (string[i] == ' ' and i > wrap) {
                out[i] = '\n';
                wrap += 20;
            }
            else {
                out[i] = string[i];
            }
        }

        return &out;
    }
}```
very bad code, im in a rush
ruby palm
#

var out: [string.len:0]u8 = undefined;
seems bit suspicious since it's suspposed to represent null terminated array yet undefined is assigned to it. Maybe remove the null sentinel and use 0..string.len in the for loop

thin garden
#

i need the null sentinel for a library

ruby palm
#

you can write the null byte at the end of the out and return slice with null terminator

thin garden
#

its a wrapper around a clibrary that requires [:0]const u8 specifcally

ruby palm
#

also out has to be longer than string.len, since you'll be adding new characters to it.
In comptimes it's usually easier to have dynamic arrays using concatenate operator

#

you can cast to appropriate type on return, is what i meant

thin garden
#

iirc [:0] increases the array by 1 invisibily for the null character

ruby palm
#

but you need space for the \ns you're adding

#

oh you're replacing spaces

thin garden
#

im replacing spaces

#

yep

#

i dont know how to cast from []const u8 to [:0] const u8 at comptime

#

the above code gives global variable contains reference to comptime var

ruby palm
#

hmm maybe can just do it in place, something like:

fn wrapStr(comptime string: []const u8) [:0]const u8 {
  var wrap = 20;
  var out: [string.len:0]u8 = string.*;

  for (0..out.len) |i| {
    if (out[i] == ' ' and i > wrap) {
      out[i] = '\n';
      wrap += 20;
    }
  }

  return &out;
}
thin garden
#

which makes sense, its returning a slice/pointer, but im not sure how else

ruby palm
#

can return array

thin garden
#

is comptime not needed?

ruby palm
thin garden
#

getting index syntax required for slice type '[]const u8'

ruby palm
#

yeah, couldn't remember, have to use string.ptr.* then

thin garden
#

same error message wierdly

#

not sure how this would work, even tho its comptime its being equalled to a ptr

ruby palm
#

oh it wants comptime length

#

var out: [string.len:0]u8 = string[0..string.len].*;

thin garden
#

still nope, i tried

#

it cant convert implicitly non sentinel to sentinel pretty sure

ruby palm
#

ah right, original doesn't have sentinel. Then will have to add it manually

#

wait no it does, specify in the type since in zig literals by default have the 0 sentinel to be compatible with C when needed

#

comptime string: [:0]const u8, will work in your case of const mystr: [:0]u8 = wrapStr("Some long text 123 abc efg hij klm nop")

thin garden
#

maybe thisi s impossible in zig ;/

#

not at comptime

#
fn wrapStr(comptime string: [:0]const u8) [:0]const u8 {
  var wrap = 20;
  var out: [string.len:0]u8 = string[0..string.len].*;

  for (0..out.len) |i| {
    if (out[i] == ' ' and i > wrap) {
      out[i] = '\n';
      wrap += 20;
    }
  }

  return &out;
}```
this just gives the same error message as mine
#

can i not return some "comptime literal" instead of a slice

#

i find this wierd, is there no way to return a N sized array? its all pointers.

ruby palm
#

right, not sure what global variable it's talking about there

thin garden
#

can i not do fn wrapStr(...) [N:0]const u8 {...}

ruby palm
#

i'm not sure if this works, but hopefuly it does:

fn wrapStr(comptime string: [:0]const u8) [string.len:0]u8 {
thin garden
#

oh i did it

#

that worked

ruby palm
#

(removed const, this isn't pointer)

thin garden
#

wow

#

works flawlessly

#

syntax for pointers/slices/fixed is so similar i think its bad

#

i barely know the idfferences between [*]u8 and *[]u8 and []u8

ruby palm
#

yeah, zig comptime needs to get used to, but it blurs the line between runtime logic and comptime. Like in other languages you'd need to use some generic N, while here you can use string.len in comptime context

thin garden
ruby palm
#

the syntax for pointers and slices is fine to be similar, since both are pointer types. As for array type, it follows C style of [N], but that is pretty similar to [*] and []

thin garden
#

thank you for helping, im so lost with comptime

thin garden
ruby palm
#

think of slices as pointers with length. So if array is the byte sequence, slice is a pointer to this byte sequence with amount of elements coupled with it

thin garden
#

yes but at comptime, even a non slice pointer you still know the length of

#

so a pointer and a slice is the same at comptime or should be the same

ruby palm
#

yeah which sort of makes it simpler since you can use both, but have to keep in mind that in one case you're passing around value and in other case passing around pointer to the value