Re: char* pointers between C and D
On 7/25/22 06:51, ryuukk_ wrote: > On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote: >> const(char)[] ch1 = "Hello World!"; >> char[] ch2="Hello World!".dup; [...] > `ch1`is a string literal, just like in C, it is null terminated To be pedantic, ch1 is not the string literal but a slice of it. "Hello world" is the string literal and does have a '\0' at the end. > `ch2` is a GC allocated char array, it is NOT null terminated Yes. The only difference between ch1 and ch2 is that ch1 does not incur an allocation cost. Ali
Re: char* pointers between C and D
This is how to do it the D way: ``` int main(string[] args) { string ch1 = "Hello World!"; char[] ch2="Hello World!".dup; string s1=ch1[1..$]; char[] s2=ch2[1..$]; writeln(s1); writeln(s2); return 0; } ```
Re: char* pointers between C and D
On Mon, Jul 25, 2022 at 05:30:14PM +, pascal111 via Digitalmars-d-learn wrote: [...] > int main(string[] args) > { > > > const(char)[] ch1 = "Hello World!"; > char[] ch2="Hello World!".dup; > > const(char) *p1; > char *p2; > > ch2~="\0"; > > p1=ch1.ptr; > p2=ch2.ptr; > > writeln(p1[0..strlen(p1)]); > writeln(p2[0..strlen(p2)]); Unless you are passing the string back to C code as char*, there is no need to use strlen here. You can just use `writeln(p1);` to output the entire string, or slice it with `p1[0 .. $]` to get the entire string. T -- Being able to learn is a great learning; being able to unlearn is a greater learning.
Re: char* pointers between C and D
On Monday, 25 July 2022 at 13:51:35 UTC, ryuukk_ wrote: On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote: On Monday, 25 July 2022 at 09:36:05 UTC, ryuukk_ wrote: [...] I tried your advice with two ways; once with a constant and other with an array, but the result isn't the same. The array case has more letters in the output. module main; import std.stdio; import core.stdc.stdio; import core.stdc.string; int main(string[] args) { const(char)[] ch1 = "Hello World!"; char[] ch2="Hello World!".dup; const(char) *p1; char *p2; p1=ch1.ptr; p2=ch2.ptr; writeln(p1[0..strlen(p1)]); writeln(p2[0..strlen(p2)]); return 0; } Runtime output: https://i.postimg.cc/sfnkJ4GM/Screenshot-from-2022-07-25-13-12-03.png `ch1`is a string literal, just like in C, it is null terminated `ch2` is a GC allocated char array, it is NOT null terminated `strlen` is the lib C function, it counts strings up to `\O` for `p1` it'll print correctly, it is a pointer from the null terminated string for `p2` strlen doesn't make sense, since it is a pointer from a string that is NOT null terminated Yes, I have to add "\0": module main; import std.stdio; import core.stdc.stdio; import core.stdc.string; int main(string[] args) { const(char)[] ch1 = "Hello World!"; char[] ch2="Hello World!".dup; const(char) *p1; char *p2; ch2~="\0"; p1=ch1.ptr; p2=ch2.ptr; writeln(p1[0..strlen(p1)]); writeln(p2[0..strlen(p2)]); return 0; }
Re: char* pointers between C and D
On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote: On Monday, 25 July 2022 at 09:36:05 UTC, ryuukk_ wrote: Here is the way to do it with `writefln` (i think) ```D import std; import core.stdc.string; void main() { const(char)[] ch = "Hello World!"; const(char)[] ch2 = "abc"; const(char)* p; p = &ch[0]; p++; auto str = p[0 .. strlen(p)]; writefln("%s", str); } ``` Note that i removed your `.dup` it is unecessary, string literals needs `const(char)` After looking at the doc, `writefln` needs a slice, so we just do that and pass it I tried your advice with two ways; once with a constant and other with an array, but the result isn't the same. The array case has more letters in the output. module main; import std.stdio; import core.stdc.stdio; import core.stdc.string; int main(string[] args) { const(char)[] ch1 = "Hello World!"; char[] ch2="Hello World!".dup; const(char) *p1; char *p2; p1=ch1.ptr; p2=ch2.ptr; writeln(p1[0..strlen(p1)]); writeln(p2[0..strlen(p2)]); return 0; } Runtime output: https://i.postimg.cc/sfnkJ4GM/Screenshot-from-2022-07-25-13-12-03.png `ch1`is a string literal, just like in C, it is null terminated `ch2` is a GC allocated char array, it is NOT null terminated `strlen` is the lib C function, it counts strings up to `\O` for `p1` it'll print correctly, it is a pointer from the null terminated string for `p2` strlen doesn't make sense, since it is a pointer from a string that is NOT null terminated
Re: char* pointers between C and D
On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote: module main; import std.stdio; import core.stdc.stdio; import core.stdc.string; int main(string[] args) { const(char)[] ch1 = "Hello World!"; char[] ch2="Hello World!".dup; const(char) *p1; char *p2; p1=ch1.ptr; p2=ch2.ptr; writeln(p1[0..strlen(p1)]); writeln(p2[0..strlen(p2)]); return 0; } Runtime output: https://i.postimg.cc/sfnkJ4GM/Screenshot-from-2022-07-25-13-12-03.png Do not post screenshots of text. `strlen` only works on null-terminated strings. The result of `.dup` is not null-terminated, so `strlen` doesn't work on it.
Re: char* pointers between C and D
On Monday, 25 July 2022 at 09:36:05 UTC, ryuukk_ wrote: Here is the way to do it with `writefln` (i think) ```D import std; import core.stdc.string; void main() { const(char)[] ch = "Hello World!"; const(char)[] ch2 = "abc"; const(char)* p; p = &ch[0]; p++; auto str = p[0 .. strlen(p)]; writefln("%s", str); } ``` Note that i removed your `.dup` it is unecessary, string literals needs `const(char)` After looking at the doc, `writefln` needs a slice, so we just do that and pass it I tried your advice with two ways; once with a constant and other with an array, but the result isn't the same. The array case has more letters in the output. module main; import std.stdio; import core.stdc.stdio; import core.stdc.string; int main(string[] args) { const(char)[] ch1 = "Hello World!"; char[] ch2="Hello World!".dup; const(char) *p1; char *p2; p1=ch1.ptr; p2=ch2.ptr; writeln(p1[0..strlen(p1)]); writeln(p2[0..strlen(p2)]); return 0; } Runtime output: https://i.postimg.cc/sfnkJ4GM/Screenshot-from-2022-07-25-13-12-03.png
Re: char* pointers between C and D
On Monday, 25 July 2022 at 09:04:29 UTC, pascal111 wrote: I have small C program that uses a pointer to change the start address of a string, and when I tried to do the same code but with D, the D code printed the address of the string after I increased it one step instead of printing the string the pointer pointing to. Is there a difference between "char *" pointers between C and D. No, no difference. Pointers are the same in both languages. What's different is the behavior of `%s` in `writeln` vs `printf`. See the documentation on format strings at: https://dlang.org/phobos/std_format.html Essentially, `%s` tells the formatter to output something appropriate for the given type. For an actual D string, you see the text. For an integral or floating point type, you see the number. For a pointer, you see the the address. And so on. Do in your case, to get `writefln` to print the text instead of the pointer address, you could import `std.string` and use `fromStringz`:`fromStringz(p)`. This will give you a D string without allocating any memory. Basically an immutable slice of the memory pointed at by `p`. That's fine for this use case, but if you wanted to hang on to the string beyond the lifetime of the pointer, you'd have to use `std.conv.to` instead (e.g., `to!string(p)`).
Re: char* pointers between C and D
Here is the way to do it with `writefln` (i think) ```D import std; import core.stdc.string; void main() { const(char)[] ch = "Hello World!"; const(char)[] ch2 = "abc"; const(char)* p; p = &ch[0]; p++; auto str = p[0 .. strlen(p)]; writefln("%s", str); } ``` Note that i removed your `.dup` it is unecessary, string literals needs `const(char)` After looking at the doc, `writefln` needs a slice, so we just do that and pass it
Re: char* pointers between C and D
I don't know what `writefln` is doing, but this following D code is the exact similar to your C code ``` import core.stdc.stdio; void main() { const(char)[] ch = "Hello World!"; const(char)* p; p = &ch[0]; p++; printf("%s", p); } ``` `ello World!`
char* pointers between C and D
I have small C program that uses a pointer to change the start address of a string, and when I tried to do the same code but with D, the D code printed the address of the string after I increased it one step instead of printing the string the pointer pointing to. Is there a difference between "char *" pointers between C and D. #include #include int main() { char ch[]="Hello World!"; char *p; p=&ch; p++; printf("%s\n", p); return 0; } module main; import std.stdio; int main(string[] args) { char[] ch="Hello World!".dup; char *p; p=&ch[0]; p++; writefln("%s", p); return 0; }