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