0

For example where an external C library is returning a fixed-size buffer containing a null-terminated string.

What would be the the equivalent of strcmp() to compare these two buffers? std.mem.eql fails because they are different sizes.

var string1: [1024]u8 = undefined;
@memset(&string1, 0);
@memcpy(string1[0..3], "foo");

var string2 = "foo";

var result = std.mem.eql(u8, &string1, string2);
try std.testing.expect(result);
snowcrash09
  • 4,694
  • 27
  • 45

2 Answers2

1

I'd suggest turning your string into a proper slice using std.mem.len:

var buffer: [1024]u8 = undefined;
@memset(&buffer, 0);
@memcpy(buffer[0..3], "foo");

const length = std.mem.len(@as([*:0]u8, @ptrCast(&buffer)));
var string1 = buffer[0..length];
var string2 = "foo";

var result = std.mem.eql(u8, string1, string2);
try std.testing.expect(result);

Or use std.mem.span:

var buffer: [1024]u8 = undefined;
@memset(&buffer, 0);
@memcpy(buffer[0..3], "foo");

var string1 = std.mem.span(@as([*:0]u8, @ptrCast(&buffer)));
var string2 = "foo";

var result = std.mem.eql(u8, string1, string2);
try std.testing.expect(result);
sigod
  • 3,514
  • 2
  • 21
  • 44
  • std.mem.len is what I was looking for, thank you. Maybe there should be a utility in std that produces a slice in the way you suggest. – snowcrash09 Sep 02 '23 at 12:43
  • Oh, I forgot, there is such a function: `std.mem.span`. I've updated the answer. – sigod Sep 02 '23 at 14:08
-1

You could also use std.zig.c_builtins.__builtin_strcmp:

var result = std.zig.c_builtins.__builtin_strcmp(&string1, string2) == 0;

A possible advantage of this is that this will ideally have O(min(strlen(string1), strlen(string2))) runtime, whereas first calling strlen (std.mem.len or std.mem.span) on string1 will yield O(strlen(string1) + strlen(string2)).

Luatic
  • 8,513
  • 2
  • 13
  • 34