#No builtin function for bytes -> ascii ??

1 messages · Page 1 of 1 (latest)

half anvil
#

Do we really have to impl our own function to convert the ascii to its corresponding string represention?
something like this??

const std = @import("std");

pub fn asciiToString(allocator: std.mem.Allocator, ascii_numbers: []const u8) ![]u8 {
    var result = try allocator.alloc(u8, ascii_numbers.len);
    errdefer allocator.free(result);

    for (ascii_numbers, 0..) |num, i| {
        if (num < 32 or num > 126) {
            return error.InvalidASCII;
        }
        result[i] = num;
    }

    return result;
}

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    defer _ = gpa.deinit();
    const allocator = gpa.allocator();

    const ascii_numbers = [_]u8{ 72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33 };
    const string = try asciiToString(allocator, &ascii_numbers);
    defer allocator.free(string);

    std.debug.print("Converted string: {s}\n", .{string});
}

any help is appreciated .

pure crest
#

you can just print("{s}\n", .{ascii_numbers})? this doesnt seem like a super helpful function

half anvil
#

dead 💀 thats exactly right. thank you. lol

#

im new :3

#

over engineering

quasi reef
#

Also, you know you can use a string literal, yes?

half anvil
#

yes. but i have a funciton that returns bytes.

quasi reef
#

Strings are bytes

#

There's nothing special about strings in Zig

half anvil
#

&[_]u8{}

quasi reef
#
const ascii_number: []u8 = "Hello, World!";

would achieve exactly what your example code's ascii_numbers definition does

half anvil
#

i was referring to something like its ascii code rep.

#

const str = &[_]u8{ 72, 101, 108, 108, 111 }; // "Hello"

quasi reef
#
const str = &"Hello";
#

This does the same thing

#

(er, I'm actually not totally sure that you can directly take a reference of a string literal that way, tbh)

pure crest
#

you can but thats probably not the type you want

quasi reef
#

Yeah, it is weird to do in the first place

pure crest
#

&"Hello" would be *const *const [5:0]u8, theres generally just no reason to have a pointer to a pointer like that

#

strings are already pointers

opaque gulch
#

const ascii = bytes; congratulations you have asciiToString; ASCII is just a way to interpret bytes (and why does discord not scroll threads)

half anvil
#

lol. let me jsut post my function. im trying to impl cat my self (very simple dont make fun :3)
please let me know what i could do better.

fn cat(allocator: Allocator, file: []u8) !void {
    const file_ = try std.fs.cwd().openFile(file, .{});
    defer file_.close();

    const file_bytes = try file_.getEndPos();
    const writer = std.io.getStdOut().writer();
    const contents = try file_.readToEndAlloc(allocator, file_bytes);
    defer allocator.free(contents);

    try writer.writeAll(contents);
}

in main:

    var gpa = std.heap.GeneralPurposeAllocator(.{}).init;
    defer _ = gpa.deinit();

    const gpaAlloc = gpa.allocator();

...
...
...

    const args = try std.process.argsAlloc(gpaAlloc);
    defer std.process.argsFree(gpaAlloc, args);

    if (args.len < 2) {
        std.log.err("Usage: {s} [filename2 to cat]... \n", .{args[0]});
        std.process.exit(1);
    }
    for (args[1..]) |arg| {
        std.debug.print("-----Contencts Of {s}-----\n", .{arg});
        cat(gpaAlloc, arg) catch |err| {
            std.log.err("There was an error reading from: {s}\n{s}\n", .{ arg, @errorName(err) });
        };
half anvil
opaque gulch
#

strings in zig have no notion of encoding, []const u8 is just a list of bytes, they could be ASCII, they could be UTF8, they could be Latin-1, they could be EBCDIC, etc

half anvil
#

oh ok that makes sense.

opaque gulch
#

and if you're just reading the bytes and writing them to another stream, you don't care how they're encoded; as far as you know they could be some esoteric encoding; but you do know they're bytes, and you know how many bytes there are

undone wren
#

Yeah - bytes are the universal "piece of data" type, essentially.
Every other type of data can be interpreted as simply a sequence of bytes.
... because that's ultimately all everything is.

quasi reef
#

Yes but actually no

quasi reef
#

If I have a u3 in a packed struct, for instance, that isn't bytes, that's 3 bits

undone wren
#

Packed means "remove all implicit padding."

#

It's generally going to be inefficient if you use it, but it makes sense in certain situations.
Like if you're making a struct that is going to be sent over the wire, perhaps - where the padding bytes might just be a waste of transmission.

quasi reef
next sierra
#

i don't think it's arbitrary -- in almost every ISA, the smallest unit you can address as an assembly programmer is the byte

#

cache lines are important to be aware of, but only for performance concerns, not semantic

quasi reef
undone wren
quasi reef
#

Agreed :)

next sierra