how to write a string to a c pointer?

FG via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Mar 5 05:57:43 PST 2015


On 2015-03-05 at 10:42, Kagamin wrote:
> string s;
> char[] b = cast(char[])asArray();
> b[0..s.length] = s[];

It's a bit more complicated than that if you include cutting string for buffers with smaller capacity, doing so respecting UTF-8, and adding a '\0' sentinel, since you may want to use the string in C (if I assume correctly). The setString function does all that:



import std.stdio, std.range, std.c.stdlib;

class Buffer {
     private void *ptr;
     private int size;
     private int _cap;

     public this(int cap) { ptr = malloc(cap); this._cap = cap; }
     public ~this() { free(ptr); }
     public ubyte[] asArray() { ubyte[] ret = (cast(ubyte*)ptr)[0..cap]; return ret; }
     public void* getPtr() { return ptr; }
     public int cap() { return _cap; }
}

int setString(Buffer buffer, string s)
{
     assert(buffer.cap > 0);
     char[] b = cast(char[])buffer.asArray();
     int len = min(s.length, buffer.cap - 1);
     int break_at;
     // The dchar is essential in walking over UTF-8 code points.
     // break_at will hold the last position at which the string can be cleanly cut
     foreach (int i, dchar v; s) {
         if (i == len) { break_at = i; break; }
         if (i > len) break;
         break_at = i;
     }
     len = break_at;
     b[0..len] = s[0..len];

     // add a sentinel if you want to use the string in C
     b[len] = '\0';
     // you could at this point set buffer.size to len in order to use the string in D
     return len;
}

void main()
{
     string s = "ąćęłńóśźż";
     foreach (i; 1..24) {
         Buffer buffer = new Buffer(i);
         int len = setString(buffer, s);
         printf("bufsize %2d -- strlen %2d -- %s --\n", i, len, buffer.getPtr);
     }
}



Output of the program:

bufsize  1 -- strlen  0 --  --
bufsize  2 -- strlen  0 --  --
bufsize  3 -- strlen  2 -- ą --
bufsize  4 -- strlen  2 -- ą --
bufsize  5 -- strlen  4 -- ąć --
bufsize  6 -- strlen  4 -- ąć --
bufsize  7 -- strlen  6 -- ąćę --
bufsize  8 -- strlen  6 -- ąćę --
bufsize  9 -- strlen  8 -- ąćęł --
bufsize 10 -- strlen  8 -- ąćęł --
bufsize 11 -- strlen 10 -- ąćęłń --
bufsize 12 -- strlen 10 -- ąćęłń --
bufsize 13 -- strlen 12 -- ąćęłńó --
bufsize 14 -- strlen 12 -- ąćęłńó --
bufsize 15 -- strlen 14 -- ąćęłńóś --
bufsize 16 -- strlen 14 -- ąćęłńóś --
bufsize 17 -- strlen 16 -- ąćęłńóśź --
bufsize 18 -- strlen 16 -- ąćęłńóśź --
bufsize 19 -- strlen 16 -- ąćęłńóśź --
bufsize 20 -- strlen 16 -- ąćęłńóśź --
bufsize 21 -- strlen 16 -- ąćęłńóśź --
bufsize 22 -- strlen 16 -- ąćęłńóśź --
bufsize 23 -- strlen 16 -- ąćęłńóśź --




More information about the Digitalmars-d-learn mailing list