Jump to page: 1 2
Thread overview
char* pointers between C and D
Jul 25, 2022
pascal111
Jul 25, 2022
ryuukk_
Jul 25, 2022
ryuukk_
Jul 25, 2022
pascal111
Jul 25, 2022
ag0aep6g
Jul 25, 2022
ryuukk_
Jul 25, 2022
pascal111
Jul 25, 2022
H. S. Teoh
Aug 09, 2022
Ali Çehreli
Jul 25, 2022
Kagamin
Jul 25, 2022
Mike Parker
July 25, 2022

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;

}

July 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!

July 25, 2022

Here is the way to do it with writefln (i think)

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

July 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)).

July 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)

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

July 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.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.

July 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:

>

Here is the way to do it with writefln (i think)

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

ch1is 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

July 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:

>

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

ch1is 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;
}
July 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.
July 25, 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;
}
« First   ‹ Prev
1 2