Строковые буферы и слайсы в Zig

Я в курсе, что Zig пока не идеален для любителей, но все же я пытался написать простенькую консольную программу, которая спрашивает у пользователя его имя, потом фамилию и в конце печатает "Your name is x и твоя фамилия y", просто чтобы посмотреть, смогу ли я.

Я придумал это в основном путем копирования и вставки примеров:

const std = @import("std");
const print = std.debug.print;

pub fn main() !void {
    const stdin = std.io.getStdIn().reader();

    var buf: [100]u8 = undefined;

    print("What's your first name? ", .{});
    var fname = (try stdin.readUntilDelimiterOrEof(buf[0..], '\n')).?;

    print("What's your last name? ", .{});
    var lname = (try stdin.readUntilDelimiterOrEof(buf[0..], '\n')).?;

    print("Your first name is {s} and your last name is {s}\n", .{fname, lname});
}

Теперь это компилируется, но не делает то, что я думал. Это связано с тем, что readUntilDelimiterOrEof() возвращает срез, поэтому второй вызов перезаписывает содержимое переменной fname.

Я могу создать переменную pos, которая отслеживает положение в буфере (например, fname.len), а затем сохранить следующий ввод в buf[pos..] вместо buf[0..], но это неуклюже, и я не Не думаю, что это то, что должен делать буфер.

Вместо этого я пытаюсь заставить fname и lname содержать свои копии среза в некоторой форме (массив?) и сохранять каждый пользовательский ввод в buf[0..], но без особого успеха. Я прочитал пару предложений. Присвоение новой переменной с помощью fname[0..(fname.len)].* не компилируется. Он работает только с числовым литералом, скажем, fname[0..5].*. std.mem.copy работает с (fname.len), но строка, похоже, не завершается нулем, потому что печать в конце программы печатает имя, а затем вопросительные знаки до размера, назначенного этой новой переменной .

Каков был бы разумный, идиоматический способ реализации этой элементарной программы? Спасибо.

Структурированный массив Numpy
Структурированный массив Numpy
Однако в реальных проектах я чаще всего имею дело со списками, состоящими из нескольких типов данных. Как мы можем использовать массивы numpy, чтобы...
T - 1Bits: Генерация последовательного массива
T - 1Bits: Генерация последовательного массива
По мере того, как мы пишем все больше кода, мы привыкаем к определенным способам действий. То тут, то там мы находим код, который заставляет нас...
Что такое деструктуризация массива в JavaScript?
Что такое деструктуризация массива в JavaScript?
Деструктуризация позволяет распаковывать значения из массивов и добавлять их в отдельные переменные.
0
0
168
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Использование распределителя было бы более идиоматично:

const std = @import("std");
const print = std.debug.print;

pub fn main() !void {
    // It can be any allocator, not just FBA
    var buffer: [128]u8 = undefined;
    var fba = std.heap.FixedBufferAllocator.init(&buffer);
    const allocator = fba.allocator();

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

    print("What's your first name? ", .{});
    var fname = (try stdin.readUntilDelimiterOrEofAlloc(allocator, '\n', max_size)).?;
    defer allocator.free(fname);
    
    print("What's your last name? ", .{});
    var lname = (try stdin.readUntilDelimiterOrEofAlloc(allocator, '\n', max_size)).?;
    defer allocator.free(lname);
    
    print("Your first name is {s} and your last name is {s}\n", .{fname, lname});
}

Тем не менее, ваша попытка не так уж плоха и имеет свое применение. Вы можете исправить это, определив буфер как слайс и обновляя его каждый раз, когда вы что-то в него записываете:

var memory: [100]u8 = undefined;
var buffer: []u8 = &memory;

print("What's your first name? ", .{});
var fname = (try stdin.readUntilDelimiterOrEof(buffer, '\n')).?;
buffer = buffer[fname.len..];

print("What's your last name? ", .{});
var lname = (try stdin.readUntilDelimiterOrEof(buffer, '\n')).?;
buffer = buffer[lname.len..];

print("Your first name is {s} and your last name is {s}\n", .{fname, lname});

Другие вопросы по теме