digitalmars.D.learn - char* pointers between C and D
- pascal111 (28/28) Jul 25 2022 I have small C program that uses a pointer to change the start
- ryuukk_ (14/14) Jul 25 2022 I don't know what `writefln` is doing, but this following D code
- ryuukk_ (20/20) Jul 25 2022 Here is the way to do it with `writefln` (i think)
- pascal111 (22/42) Jul 25 2022 I tried your advice with two ways; once with a constant and other
- ag0aep6g (4/22) Jul 25 2022 Do not post screenshots of text.
- ryuukk_ (8/56) Jul 25 2022 `ch1`is a string literal, just like in C, it is null terminated
- pascal111 (19/64) Jul 25 2022 Yes, I have to add "\0":
- H. S. Teoh (8/25) Jul 25 2022 Unless you are passing the string back to C code as char*, there is no
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/12) Aug 09 2022 To be pedantic, ch1 is not the string literal but a slice of it. "Hello
- Kagamin (13/13) Jul 25 2022 This is how to do it the D way:
- Mike Parker (17/23) Jul 25 2022 No, no difference. Pointers are the same in both languages.
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 <stdio.h> #include <stdlib.h> 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; }
Jul 25 2022
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!`
Jul 25 2022
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
Jul 25 2022
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 itI 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
Jul 25 2022
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.pngDo 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.
Jul 25 2022
On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote:On Monday, 25 July 2022 at 09:36:05 UTC, ryuukk_ wrote:`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 terminatedHere 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 itI 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
Jul 25 2022
On Monday, 25 July 2022 at 13:51:35 UTC, ryuukk_ wrote:On Monday, 25 July 2022 at 11:14:56 UTC, pascal111 wrote: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; }On Monday, 25 July 2022 at 09:36:05 UTC, ryuukk_ wrote:`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[...]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
Jul 25 2022
On Mon, Jul 25, 2022 at 05:30:14PM +0000, 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.
Jul 25 2022
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 terminatedTo 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 terminatedYes. The only difference between ch1 and ch2 is that ch1 does not incur an allocation cost. Ali
Aug 09 2022
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; } ```
Jul 25 2022
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)`).
Jul 25 2022