Re: char* pointers between C and D

2022-08-09 Thread Ali Çehreli via Digitalmars-d-learn

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

2022-07-25 Thread Kagamin via Digitalmars-d-learn

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

2022-07-25 Thread H. S. Teoh via Digitalmars-d-learn
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

2022-07-25 Thread pascal111 via Digitalmars-d-learn

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

2022-07-25 Thread ryuukk_ via Digitalmars-d-learn

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

2022-07-25 Thread ag0aep6g via Digitalmars-d-learn

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

2022-07-25 Thread pascal111 via Digitalmars-d-learn

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

2022-07-25 Thread Mike Parker via Digitalmars-d-learn

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

2022-07-25 Thread ryuukk_ via Digitalmars-d-learn

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

2022-07-25 Thread ryuukk_ via Digitalmars-d-learn
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

2022-07-25 Thread pascal111 via Digitalmars-d-learn
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;
}