Biggest problems w/ D - strings
Regan Heath
regan at netmail.co.nz
Sat Aug 11 16:10:47 PDT 2007
Sean Kelly wrote:
> C. Dunn wrote:
>> BCS Wrote:
>>
>>> Reply to Sean,
>>>
>>>> C. Dunn wrote:
>>>>
>>>>> I have a field of n chars stored on disk. It holds a null-terminated
>>>>> string, padded with zeroes. It is amazingly difficult to compare
>>>>> such a char[n] with some other char[] (which, by the dictates of D,
>>>>> may or may not be null-terminated).
>>>>>
>>>> I'm not sure I understand. Why bother computing string length in the
>>>> C fashion when D provides a .length property which holds this
>>>> information?
>>>>
>>>> Sean
>>>>
>>> He might be using a D char[] as an oversized buffer for a c style
>>> string.
>>
>> Exactly. This is very common in the database world. The disk record
>> has a fixed size, so I have a struct which looks like this:
>>
>> struct Data{
>> int id;
>> char[32] name;
>> // ...
>> };
>>
>> A C function produces this data. D can accept the C struct with no
>> problems. 'name' is just a static array. But processing the name
>> field in D is awkward. 'name.length' is 32, but 'strlen(name)' could
>> be less (or infinity if the string is a full 32 characters sans
>> zeroes, which is why I need strnlen()).
>
> Oh I see. Well, it isn't much help, but std::string in C++ isn't
> null-terminated either, so this issue isn't unique to D. Unfortunately,
> I think a custom comparator, like the one you've written, is the best
> choice here. That or property methods to make Data act more D-like. The
> get/set routines could return and accept 'normal' D strings, perform
> length validation, etc.
Something like this: (borrowing from Derek's solution, which I quite
liked BTW)
import std.string, std.stdio;
// 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];
}
struct Data
{
int id;
char[32] _name;
string name() { return lefts(_name, '\0'); }
}
Data zero;
Data full;
Data some;
static this()
{
zero._name[] = '\0';
full._name[] = 'a';
some._name[0..10] = 'a';
some._name[10..$] = '\0';
}
void main()
{
char[] other;
other.length = 10;
other[] = 'a';
assert(other != zero.name);
assert(other != full.name);
assert(other == some.name);
}
Regan
More information about the Digitalmars-d
mailing list