digitalmars.D.bugs - [Issue 1393] New: Phobos needs strnlen()
- d-bugmail puremagic.com (68/68) Jul 31 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1393
- d-bugmail puremagic.com (31/31) Aug 14 2007 http://d.puremagic.com/issues/show_bug.cgi?id=1393
http://d.puremagic.com/issues/show_bug.cgi?id=1393 Summary: Phobos needs strnlen() Product: D Version: 1.015 Platform: PC OS/Version: Linux Status: NEW Severity: enhancement Priority: P2 Component: Phobos AssignedTo: bugzilla digitalmars.com ReportedBy: cdunn2001 gmail.com std.c.string needs strnlen(). Here is why: struct Person{ char name[32]; char addr[128]; }; A bunch of these could be stored on disk. After loading, we want to compare 'name' to another array. But how? We can use strncmp(), but we need to know the length of 'name'. It is NOT 32. We cannot use strlen() safely on 'name' because it might not be null-terminated. We need to do this: --- int compare(char[] lhs, char[] rhs){ char* lptr = cast(char*)lhs; char* rptr = cast(char*)rhs; ulong len_lhs = strnlen(lptr, lhs.length); ulong len_rhs = strnlen(rptr, rhs.length); int comp = std.c.string.strncmp(lptr, rptr, min!(uint)(len_lhs, len_rhs)); if (comp) return comp; if (len_lhs < len_rhs) return -1; else if (len_lhs > len_rhs) return 1; else return 0; } bool foo(Person* p){ return !compare(p.name, "Christopher"); } --- Of course, std.string.strlen(char[] s) could also be useful. It should return the length to the first null, or s.length. And my compare() function could be there too. But those are not critical. strnlen() is. If it's not there, people will use strlen() and cause buffer overflows. From the Linux man page: ------------------------ SYNOPSIS #include <string.h> size_t strnlen(const char *s, size_t maxlen); DESCRIPTION The strnlen function returns the number of characters in the string pointed to by s, not including the terminating '\0' character, but at most maxlen. In doing this, strnlen looks only at the first maxlen characters at s and never beyond s+maxlen. RETURN VALUE The strnlen function returns strlen(s), if that is less than maxlen, or maxlen if there is no '\0' character among the first maxlen characters pointed to by s. CONFORMING TO This function is a GNU extension. ----------- And here is a simple implementation: ulong strnlen(char* s, ulong maxlen){ for(ulong i=0; i<maxlen; ++i){ if (!s[i]) return i; } return maxlen; } [I used ulong, since a UNIX string could be an entire file.] --
Jul 31 2007
http://d.puremagic.com/issues/show_bug.cgi?id=1393 cdunn2001 gmail.com changed: What |Removed |Added ---------------------------------------------------------------------------- Status|NEW |RESOLVED Resolution| |WORKSFORME Derek Parnell suggested slicing as a solution: import std.string; /** Return a slice of the leftmost portion of 'x' up to but not including the first 'c' */ string lefts(string x, char c) { int p; p = std.string.find(x,c); if (p < 0) p = x.length; return x[0..p]; } int compare(string lhs, string rhs, char d = '\0') { return std.string.cmp( lefts(lhs,d), lefts(rhs,d) ); } and use it like ... char[32] NameA = '\0'; char[56] NameB = '\0'; NameA[0..5] = "derek"; NameB[0..7] = "parnell"; result = compare(NameA, NameB); This is simple enough for me. --
Aug 14 2007