Re: Find a char among string (string.findAmong.char)

2021-07-07 Thread rassoc via Digitalmars-d-learn

On Wednesday, 7 July 2021 at 12:22:11 UTC, BoQsc wrote:

I think nested foreach loops are more readable.

```
import std;
void main()
{
alias alphabet = letters;
char[26] letters = ['a','b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'];

string wordExample = "Book.";
foreach (letter; wordExample){
foreach (alphabetLetter; letters){
if (letter == alphabetLetter) {
writeln(letter);
}
}

}

}
```


Use whatever fits your style best or what you are most familar 
with. But be aware that there's a concise alternative:


```d
import std;
void main()
{
import std.ascii; // because there's also std.uni.isLower
"Book.".filter!isLower.each!writeln;  
}
```

or alternatively with fully-qualified naming:

```d
import std;
void main()
{
   "Book.".filter!(std.ascii.isLower).each!writeln; 
  
}
```


Re: Find a char among string (string.findAmong.char)

2021-07-07 Thread BoQsc via Digitalmars-d-learn

I think nested foreach loops are more readable.

```
import std;
void main()
{
alias alphabet = letters;
char[26] letters = ['a','b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'];

string wordExample = "Book.";
foreach (letter; wordExample){
foreach (alphabetLetter; letters){
if (letter == alphabetLetter) {
writeln(letter);
}
}

}

}
```


Re: Find a char among string (string.findAmong.char)

2021-07-06 Thread BoQsc via Digitalmars-d-learn

On Tuesday, 6 July 2021 at 15:48:35 UTC, rassoc wrote:

You can also do:

```d
import std;
void main()
{
// https://dlang.org/phobos/std_ascii.html#.lowercase
"Book.".filter!(c => lowercase.canFind(c))
   .each!(c => writeln(c, " found"));

// Output:
// o found
// o found
// k found
}
```


I really don't like reading arrow functions.
It takes some more effort to understand, follow and get used to 
them.
I'd like something simple and effortless looking and feeling that 
would make code readable similarly to an english sentence.


Such as this, but as noted, this does not work as 
intended/assumed by me:

```
if (letter.findAmong(alphabet)){
 write("found");
 }
```


Re: Find a char among string (string.findAmong.char)

2021-07-06 Thread rassoc via Digitalmars-d-learn

You can also do:

```d
import std;
void main()
{
// https://dlang.org/phobos/std_ascii.html#.lowercase
"Book.".filter!(c => lowercase.canFind(c))
   .each!(c => writeln(c, " found"));

// Output:
// o found
// o found
// k found
}
```


Re: Find a char among string (string.findAmong.char)

2021-07-06 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 6 July 2021 at 11:35:14 UTC, BoQsc wrote:

I tried out .canFind method, and to test it I removed the 
letter 'o' from the Alphabet.
Weirdly enough .canFind method still found 'o' letter among the 
Alphabet.


https://run.dlang.io/is/2Fvenf


Looks like it has something to do with the alias. Static arrays 
aren't ranges, so you should really be seeing the same error you 
would if you passed `letters` directly.


Change the `canFind` call to take a slice of the array:

```d
if (letters[].canFind(letter)){
```

And it outputs the following as expected:

```
k letter is found among the alphabet.
```

This warrants a bug report with a minimized example.


Re: Find a char among string (string.findAmong.char)

2021-07-06 Thread BoQsc via Digitalmars-d-learn

On Monday, 5 July 2021 at 19:48:13 UTC, jfondren wrote:

On Monday, 5 July 2021 at 19:34:14 UTC, BoQsc wrote:


But I really don't like how it looks less readable and makes 
less sense on first look.

`if (([letter].findAmong(alphabet)).length)`
I'd like to use some method on the `letter` instead of []
And `.length` does not make a lot of sense when reading like 
an english sentence.


I suggest canFind, like in my earlier example. findAmong is 
like "consume this range until you find one of these things, 
and then return the remainder of the range". It doesn't really 
fit your use.


I tried out .canFind method, and to test it I removed the letter 
'o' from the Alphabet.
Weirdly enough .canFind method still found 'o' letter among the 
Alphabet.


https://run.dlang.io/is/2Fvenf



Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread jfondren via Digitalmars-d-learn

On Monday, 5 July 2021 at 19:34:14 UTC, BoQsc wrote:


But I really don't like how it looks less readable and makes 
less sense on first look.

`if (([letter].findAmong(alphabet)).length)`
I'd like to use some method on the `letter` instead of []
And `.length` does not make a lot of sense when reading like an 
english sentence.


I suggest canFind, like in my earlier example. findAmong is like 
"consume this range until you find one of these things, and then 
return the remainder of the range". It doesn't really fit your 
use.


Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread BoQsc via Digitalmars-d-learn

On Monday, 5 July 2021 at 19:25:23 UTC, jfondren wrote:

On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote:
If I use `[letter].findAmong(alphabet)` in my code, it 
considers a dot (.) punctuation character as a letter.

You can see it here:
https://run.dlang.io/is/YWmaXU


It returns a zero-length array that, because it's not null, is 
true. That's why I used .length in my example.


```
$ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] 
? true : false)'

0
true
$ rdmd --eval 'writeln([].length); writeln([] ? true : false)'
0
false
```


Oh alright I think I fixed it with your guidance.
```
import std;
void main()
{
alias alphabet = letters;
char[26] letters = ['a','b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'];

string wordExample = "Book.";
foreach (letter; wordExample){
if (([letter].findAmong(alphabet)).length){

write(letter);
write(" letter is found among the alphabet.");
writeln;
}

}

}
```

But I really don't like how it looks less readable and makes less 
sense on first look.

`if (([letter].findAmong(alphabet)).length)`
I'd like to use some method on the `letter` instead of []
And `.length` does not make a lot of sense when reading like an 
english sentence.




Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread jfondren via Digitalmars-d-learn

On Monday, 5 July 2021 at 19:19:19 UTC, BoQsc wrote:
If I use `[letter].findAmong(alphabet)` in my code, it 
considers a dot (.) punctuation character as a letter.

You can see it here:
https://run.dlang.io/is/YWmaXU


It returns a zero-length array that, because it's not null, is 
true. That's why I used .length in my example.


```
$ rdmd --eval 'writeln("str"[$..$].length); writeln("str"[$..$] ? 
true : false)'

0
true
$ rdmd --eval 'writeln([].length); writeln([] ? true : false)'
0
false
```


Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread BoQsc via Digitalmars-d-learn

On Monday, 5 July 2021 at 18:59:09 UTC, jfondren wrote:

On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote:


If you replace the findAmong call with 
`[letter].findAmong(alphabet)`, this works.


Consider:

```d
import std;

void main() {
import std.ascii : alphabet = letters;

string wordExample = "Book.";
foreach (letter; wordExample) {
writefln!"%c is %sa letter"(letter, 
[letter].findAmong(alphabet).length ? "" : "not ");
writefln!"%c is %sa letter"(letter, 
alphabet.canFind(letter) ? "" : "not ");

}
writeln("___>>___finally some letters".findAmong(alphabet));
}
```


If I use `[letter].findAmong(alphabet)` in my code, it considers 
a dot (.) punctuation character as a letter.

You can see it here:
https://run.dlang.io/is/YWmaXU



Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread jfondren via Digitalmars-d-learn

On Monday, 5 July 2021 at 18:53:27 UTC, jfondren wrote:


If you replace the findAmong call with 
`[letter].findAmong(alphabet)`, this works.


Consider:

```d
import std;

void main() {
import std.ascii : alphabet = letters;

string wordExample = "Book.";
foreach (letter; wordExample) {
writefln!"%c is %sa letter"(letter, 
[letter].findAmong(alphabet).length ? "" : "not ");
writefln!"%c is %sa letter"(letter, 
alphabet.canFind(letter) ? "" : "not ");

}
writeln("___>>___finally some letters".findAmong(alphabet));
}
```



Re: Find a char among string (string.findAmong.char)

2021-07-05 Thread jfondren via Digitalmars-d-learn

On Monday, 5 July 2021 at 18:45:10 UTC, BoQsc wrote:

I get an error when I try to find that letter is among alphabet.
onlineapp.d(13): Error: template 
`std.algorithm.searching.findAmong` cannot deduce function 
from argument types `!()(immutable(char), immutable(string))`, 
candidates are:

/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694):
`findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, 
ForwardRange choices)`
  with `pred = "a == b",
   InputRange = immutable(char),
   ForwardRange = string`
  must satisfy the following constraint:
`   isInputRange!InputRange`



This is the code: You can run it at: 
https://run.dlang.io/is/5cvuUZ

 import std;
 void main()
 {
 alias alphabet = letters;
 char[26] letters = ['a','b', 'c', 'd', 'e',
 'f', 'g', 'h', 'i', 'j',
 'k', 'l', 'm', 'n', 'o',
 'p', 'q', 'r', 's', 't',
 'u', 'v', 'w', 'x', 'y', 'z'];

 string wordExample = "Book.";
 foreach (letter; wordExample){
 if (letter.findAmong(alphabet)){
 write("found");
 }
write(letter);
 }

 }


If you replace the findAmong call with 
`[letter].findAmong(alphabet)`, this works.


Both arguments to findAmong need to be ranges; you're calling it 
here against an immutable(char). As it says in the error:


```
from argument types `!()(immutable(char), immutable(string))`
```

immutable(char) looks a lot like immutable(char)[], but the 
latter is a string and the former is just a singular char.


Find a char among string (string.findAmong.char)

2021-07-05 Thread BoQsc via Digitalmars-d-learn

I get an error when I try to find that letter is among alphabet.
onlineapp.d(13): Error: template 
`std.algorithm.searching.findAmong` cannot deduce function from 
argument types `!()(immutable(char), immutable(string))`, 
candidates are:

/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/searching.d(2694):
`findAmong(alias pred = "a == b", InputRange, ForwardRange)(InputRange seq, 
ForwardRange choices)`
  with `pred = "a == b",
   InputRange = immutable(char),
   ForwardRange = string`
  must satisfy the following constraint:
`   isInputRange!InputRange`



This is the code: You can run it at: 
https://run.dlang.io/is/5cvuUZ

 import std;
 void main()
 {
 alias alphabet = letters;
 char[26] letters = ['a','b', 'c', 'd', 'e',
 'f', 'g', 'h', 'i', 'j',
 'k', 'l', 'm', 'n', 'o',
 'p', 'q', 'r', 's', 't',
 'u', 'v', 'w', 'x', 'y', 'z'];

 string wordExample = "Book.";
 foreach (letter; wordExample){
 if (letter.findAmong(alphabet)){
 write("found");
 }
write(letter);
 }

 }





Re: std.conv.to!string refuses to convert a char* to string.

2017-12-09 Thread Venkat via Digitalmars-d-learn
Thank you, core.runtime.Runtime.initialize() fixed the issue. I 
am now able to use to!string as well. I found your posts and Ali 
Çehreli's posts on this subject. I think I have some 
understanding now.


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-09 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 9 December 2017 at 06:14:36 UTC, Venkat wrote:
Thanks for the quick response. std.string.fromStringz did the 
trick. I am not sure what was the deal with to!string.


Be careful with fromStringz. It doesn't allocate a new string, so 
the returned string can easily become corrupted if the C string 
it's referencing falls off the stack.


As for your problem with to!string, it isn't actually to!string 
that's the issue. It appears to have something to do with the 
memory allocated from the GC. I assume this is a shared library. 
Random thoughts -- Have you initialized DRuntime? Have you 
registered the calling thread with the GC?


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Venkat via Digitalmars-d-learn
Thanks for the quick response. std.string.fromStringz did the 
trick. I am not sure what was the deal with to!string.


Re: std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Neia Neutuladh via Digitalmars-d-learn

On Saturday, 9 December 2017 at 05:55:21 UTC, Venkat wrote:
I am trying out the DJni library 
(https://github.com/Monnoroch/DJni). For some reason 
std.conv.to!string doesn't want to convert a char* to a 
string.The lines below are taken from the log. I see that the 
last frame is at gc_qalloc. I am not sure why it failed there. 
Can anybody elaborate on what is going on here ? Thanks in 
advance.


I've got no idea, but can you verify that you can print it with 
printf? Can you allocate other GC memory? Can you try using 
fromStringz instead of to!string and see what that does?


Just shots in the dark...


std.conv.to!string refuses to convert a char* to string.

2017-12-08 Thread Venkat via Digitalmars-d-learn
I am trying out the DJni library 
(https://github.com/Monnoroch/DJni). For some reason 
std.conv.to!string doesn't want to convert a char* to a 
string.The lines below are taken from the log. I see that the 
last frame is at gc_qalloc. I am not sure why it failed there. 
Can anybody elaborate on what is going on here ? Thanks in 
advance.


 91
 92
 93 Stack: [0x7f749dfd9000,0x7f749e0da000],  
sp=0x7f749e0d8600,  free space=1021k
 94 Native frames: (J=compiled Java code, j=interpreted, Vv=VM 
code, C=native code)

 95 C  [libPrompt.so+0x6b0cc]  gc_qalloc+0x2c
 96 C  [libPrompt.so+0x7bf18]  
_D2rt8lifetime12__arrayAllocFNaNbmxC8TypeInfoxQlZS4core6memory8BlkInfo_+0xec

 97 C  [libPrompt.so+0x6c2fa]  _d_newarrayU+0x86
 98 C  [libPrompt.so+0x593a7]  
_D6object__T4_dupTxaTaZQlFNaNbAxaZAa+0x1f
 99 C  [libPrompt.so+0x59384]  
_D6object__T11_trustedDupTxaTaZQtFNaNbNeAxaZAa+0x20
100 C  [libPrompt.so+0x59360]  
_D6object__T3dupTaZQhFNaNbNdNfAxaZAa+0x20
101 C  [libPrompt.so+0x5932a]  
_D3std4conv__T6toImplTAyaTPxaZQqFQhZ9__lambda2MFNaNbZQBf+0x3e
102 C  [libPrompt.so+0x592ea]  
_D3std4conv__T6toImplTAyaTPxaZQqFNaNbQlZQs+0x16
103 C  [libPrompt.so+0x592d1]  
_D3std4conv__T2toTAyaZ__TQlTPxaZQsFNaNbQlZQy+0x9

104 C  [libPrompt.so+0x59289]  Java_Prompt_getLine+0x61
105 j  Prompt.getLine(Ljava/lang/String;)Ljava/lang/String;+0
106 j  Prompt.main([Ljava/lang/String;)V+11
107 v  ~StubRoutines::call_stub
108 V  [libjvm.so+0x690c66]  JavaCalls::call_helper(JavaValue*, 
methodHandle*, JavaCallArguments*, Thread*)+0x1056
109 V  [libjvm.so+0x6d2072]  jni_invoke_static(JNIEnv_*, 
JavaValue*, _jobject*, JNICallType, _jmethodID*, 
JNI_ArgumentPusher*, Thread*)+0x362

110 V  [libjvm.so+0x6ee8da]  jni_CallStaticVoidMethod+0x17a
111 C  [libjli.so+0x7bdf]  JavaMain+0x81f
112 C  [libpthread.so.0+0x8184]  start_thread+0xc4
113
114 Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
115 j  Prompt.getLine(Ljava/lang/String;)Ljava/lang/String;+0
116 j  Prompt.main([Ljava/lang/String;)V+11





Re: char e string em linguagem D

2017-07-14 Thread crimaniak via Digitalmars-d-learn

On Thursday, 13 July 2017 at 22:36:47 UTC, Basile B. wrote:

  return cast(char[])`

...
Never cast a literal to char[]. modifying the resulting char[] 
will lead to AV, at least under linux.  `.dup` the literal if 
you really needs char[].


Hmm, yes, my bad. Probably, it was necessary even for this simple 
example to write const char[].


Re: char e string em linguagem D

2017-07-13 Thread dark777 via Digitalmars-d-learn

On Thursday, 13 July 2017 at 22:30:29 UTC, crimaniak wrote:

On Thursday, 13 July 2017 at 21:49:40 UTC, dark777 wrote:

Pessoal eu fiz o seguinte programa em C++.

https://pastebin.com/CvVv6Spn

porem tentei fazer o equivalente em D mas nao entendi muito 
bem...


https://pastebin.com/2xw9geRR

alguem poderia me ajudar?


Se acepta utilizar intervalos en lugar de punteros desnudos. 
(Hola, soy traductor de google)


import std.stdio, std.string;

//https://www.vivaolinux.com.br/script/GNU-que-bacana

class GnuQueBacana
{
   this(){}

  char[] stalman()
  {
  return cast(char[])`
  ((__-^^-,-^^-__))
   *---***---*
*--|o   o|--*
   \ /
): :(
(o_o)
  -
 https://www.gnu.org

`;
  }

  char[] torvald()
  {
  return cast(char[])`
#
   ###
   ##O#O##
   ###
   ##\#/##
#lll##
   #l##
   #l###
   #####
  OOO#ll#OOO
 OO#ll#OO
OOO#ll#OOO
 OOO##OOO
https://www.kernel.org

`;
  }

  string stallman()
  {
  return `
  ((__-^^-,-^^-__))
   *---***---*
*--|o   o|--*
   \ /
): :(
(o_o)
  -
 https://www.gnu.org

`;
  }

  string torvalds()
  {
  return `
#
   ###
   ##O#O##
   ###
   ##\#/##
#lll##
   #l##
   #l###
   #####
  OOO#ll#OOO
 OO#ll#OO
OOO#ll#OOO
 OOO##OOO
https://www.kernel.org

`;
  }

};

void main()
{
  GnuQueBacana gnu = new GnuQueBacana();

  writeln(gnu.stalman(), gnu.torvald(), gnu.stallman(), 
gnu.torvalds());

}


muito massa nao achei que era tao simples assim..


Re: char e string em linguagem D

2017-07-13 Thread Basile B. via Digitalmars-d-learn

On Thursday, 13 July 2017 at 22:30:29 UTC, crimaniak wrote:

On Thursday, 13 July 2017 at 21:49:40 UTC, dark777 wrote:
  char[] stalman()
  {
  return cast(char[])`
  ((__-^^-,-^^-__))
   *---***---*
*--|o   o|--*
   \ /
): :(
(o_o)
  -
 https://www.gnu.org

`;
  }



Never cast a literal to char[]. modifying the resulting char[] 
will lead to AV, at least under linux.  `.dup` the literal if you 
really needs char[].


Re: char e string em linguagem D

2017-07-13 Thread crimaniak via Digitalmars-d-learn

On Thursday, 13 July 2017 at 21:49:40 UTC, dark777 wrote:

Pessoal eu fiz o seguinte programa em C++.

https://pastebin.com/CvVv6Spn

porem tentei fazer o equivalente em D mas nao entendi muito 
bem...


https://pastebin.com/2xw9geRR

alguem poderia me ajudar?


Se acepta utilizar intervalos en lugar de punteros desnudos. 
(Hola, soy traductor de google)


import std.stdio, std.string;

//https://www.vivaolinux.com.br/script/GNU-que-bacana

class GnuQueBacana
{
   this(){}

  char[] stalman()
  {
  return cast(char[])`
  ((__-^^-,-^^-__))
   *---***---*
*--|o   o|--*
   \ /
): :(
(o_o)
  -
 https://www.gnu.org

`;
  }

  char[] torvald()
  {
  return cast(char[])`
#
   ###
   ##O#O##
   ###
   ##\#/##
#lll##
   #l##
   #l###
   #####
  OOO#ll#OOO
 OO#ll#OO
OOO#ll#OOO
 OOO##OOO
https://www.kernel.org

`;
  }

  string stallman()
  {
  return `
  ((__-^^-,-^^-__))
   *---***---*
*--|o   o|--*
   \ /
): :(
(o_o)
  -
 https://www.gnu.org

`;
  }

  string torvalds()
  {
  return `
#
   ###
   ##O#O##
   ###
   ##\#/##
#lll##
   #l##
   #l###
   #####
  OOO#ll#OOO
 OO#ll#OO
OOO#ll#OOO
 OOO##OOO
https://www.kernel.org

`;
  }

};

void main()
{
  GnuQueBacana gnu = new GnuQueBacana();

  writeln(gnu.stalman(), gnu.torvald(), gnu.stallman(), 
gnu.torvalds());

}


char e string em linguagem D

2017-07-13 Thread dark777 via Digitalmars-d-learn

Pessoal eu fiz o seguinte programa em C++.

https://pastebin.com/CvVv6Spn

porem tentei fazer o equivalente em D mas nao entendi muito bem...

https://pastebin.com/2xw9geRR

alguem poderia me ajudar?


Re: what's the right way to get char* from string?

2016-05-06 Thread ZombineDev via Digitalmars-d-learn

On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote:

Hello,

When I need to call C function, often need to
have char* pointer from string.

"Interfacing to C++" page:
https://dlang.org/spec/cpp_interface.html
have following example.

extern (C) int strcmp(char* string1, char* string2);
import std.string;
int myDfunction(char[] s)
{
return strcmp(std.string.toStringz(s), "foo");
}

but this is incorrect because toStringz() returns immutable 
pointer.

One way is to write mutable version of toStringz()

char* toStringzMutable(string s) @trusted pure nothrow {
auto copy = new char[s.length + 1];
copy[0..s.length] = s[];
copy[s.length] = 0;
return copy.ptr;
}

But I think this is common needs,
why it is not provided by Phobos?
(or tell me if it has)

Thanks,
aki


In this particular case, if you `import core.stdc.string : 
strcmp`, instead of providing your own extern declaration it 
should work, because in there the signature is correctly typed as 
`in char*` which is essentially the same as `const(char*)` which 
can accept both mutable, const and immutable arguments. Also it 
has the correct attributes so you can call it from `pure`, 
`nothrow` and `@nogc` code.


As others have said, when you do need to convert a string slice 
to a pointer to a null terminated char/wchar/dchar string, 
`toUTFz` can be very useful.


But where possible, you should prefer functions that take an 
explicit length parameter, so you can avoid memory allocation:


```
string s1, s2;
import std.algorithm : min;
import core.stdc.string : strncmp;
strncmp(s1.ptr, s2.ptr, min(s1.length, s2.length));
// (`min` is used to prevent the C function from
// accessing data beyond the smallest
// of the two string slices).
```

Also string slices that point to a **whole** string literal are 
automatically null-terminated:


```
// lit is zero-terminated
string lit = "asdf";
assert (lit.ptr[lit.length] == '\0');
assert (strlen(lit.ptr) == lit.length);
```

However you need to be very careful, because as soon as you make 
a sub-slice, this property disappears:


```
// slice is not zero-terminated.
string slice = lit[0..2];
assert (slice.ptr[length] == 'd');
assert (strlen(slice.ptr) != slice.length);
```

This means that you can't be sure that a string slice is 
zero-termninated unless you can see it in your code that it 
points to a string literal and you're sure that it would never be 
changed to point to something else (like something returned from 
a function).




Re: what's the right way to get char* from string?

2016-05-05 Thread Alex Parrill via Digitalmars-d-learn

On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote:

extern (C) int strcmp(char* string1, char* string2);


This signature of strcmp is incorrect. strcmp accepts const char* 
arguments [1], which in D would be written as const(char)*. The 
immutable(char)* values returned from toStringz are implicitly 
convertible to const(char)* and are therefore useable as-is as 
arguments to strcmp.


import std.string;
extern (C) int strcmp(const(char)* string1, const(char)* string2);
auto v = strcmp(somestring1.toStringz, somestring2.toStringz);

[1] http://linux.die.net/man/3/strcmp


Re: what's the right way to get char* from string?

2016-05-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/5/16 3:36 PM, Steven Schveighoffer wrote:

Only thing I can think of is.. um... horrible:

char *toCharz(string s)
{
auto cstr = s.toStringz;
return cstr[0 .. s.length + 1].dup.ptr;
}


Ignore this. What Jonathan said :)

-Steve



Re: what's the right way to get char* from string?

2016-05-05 Thread aki via Digitalmars-d-learn

On Thursday, 5 May 2016 at 11:35:09 UTC, Jonathan M Davis wrote:
If you want a different mutability, then use the more general 
function std.utf.toUTFz. e.g. from the documentation:


auto p1 = toUTFz!(char*)("hello world");
auto p2 = toUTFz!(const(char)*)("hello world");
auto p3 = toUTFz!(immutable(char)*)("hello world");
auto p4 = toUTFz!(char*)("hello world"d);
auto p5 = toUTFz!(const(wchar)*)("hello world");
auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);

- Jonathan M Davis


Ah! This can be a solution.
Thanks Jonathan.

-- aki.



Re: what's the right way to get char* from string?

2016-05-05 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/5/16 11:53 AM, pineapple wrote:

On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote:

Hello,

When I need to call C function, often need to
have char* pointer from string.


This might help:

import std.traits : isSomeString;
import std.string : toStringz;

extern (C) int strcmp(char* string1, char* string2);

int strcmpD0(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
const(char)[])) { // Best
 return strcmp(
 cast(char*) toStringz(lhs),
 cast(char*) toStringz(rhs)
 );
}


This is likely a correct solution, because strcmp does not modify any 
data in the string itself.


Practically speaking, you can define strcmp as taking const(char)*. This 
is what druntime does: http://dlang.org/phobos/core_stdc_string.html#.strcmp



int strcmpD1(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
const(char)[])) { // Works
 return strcmp(
 cast(char*) lhs.ptr,
 cast(char*) rhs.ptr
 );
}


Note, this only works if the strings are literals. Do not use this 
mechanism in general.



/+
int strcmpD2(S)(in S lhs, in S rhs) if(is(S == string) || is(S ==
const(char)[])) { // Breaks
 return strcmp(
 toStringz(lhs),
 toStringz(rhs)
 );
}
+/


Given a possibility that you are calling a C function that may actually 
modify the data, there isn't a really good way to do this.


Only thing I can think of is.. um... horrible:

char *toCharz(string s)
{
   auto cstr = s.toStringz;
   return cstr[0 .. s.length + 1].dup.ptr;
}

-Steve


Re: what's the right way to get char* from string?

2016-05-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Thu, 05 May 2016 07:49:46 +
aki via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote:

> Hello,
>
> When I need to call C function, often need to
> have char* pointer from string.
>
> "Interfacing to C++" page:
> https://dlang.org/spec/cpp_interface.html
> have following example.
>
> extern (C) int strcmp(char* string1, char* string2);
> import std.string;
> int myDfunction(char[] s)
> {
>  return strcmp(std.string.toStringz(s), "foo");
> }
>
> but this is incorrect because toStringz() returns immutable
> pointer.
> One way is to write mutable version of toStringz()
>
> char* toStringzMutable(string s) @trusted pure nothrow {
>  auto copy = new char[s.length + 1];
>  copy[0..s.length] = s[];
>  copy[s.length] = 0;
>  return copy.ptr;
> }
>
> But I think this is common needs,
> why it is not provided by Phobos?
> (or tell me if it has)

If you want a different mutability, then use the more general function
std.utf.toUTFz. e.g. from the documentation:

auto p1 = toUTFz!(char*)("hello world");
auto p2 = toUTFz!(const(char)*)("hello world");
auto p3 = toUTFz!(immutable(char)*)("hello world");
auto p4 = toUTFz!(char*)("hello world"d);
auto p5 = toUTFz!(const(wchar)*)("hello world");
auto p6 = toUTFz!(immutable(dchar)*)("hello world"w);

- Jonathan M Davis


Re: what's the right way to get char* from string?

2016-05-05 Thread pineapple via Digitalmars-d-learn

On Thursday, 5 May 2016 at 07:49:46 UTC, aki wrote:

Hello,

When I need to call C function, often need to
have char* pointer from string.


This might help:

import std.traits : isSomeString;
import std.string : toStringz;

extern (C) int strcmp(char* string1, char* string2);

int strcmpD0(S)(in S lhs, in S rhs) if(is(S == string) || is(S == 
const(char)[])) { // Best

return strcmp(
cast(char*) toStringz(lhs),
cast(char*) toStringz(rhs)
);
}
int strcmpD1(S)(in S lhs, in S rhs) if(is(S == string) || is(S == 
const(char)[])) { // Works

return strcmp(
cast(char*) lhs.ptr,
cast(char*) rhs.ptr
);
}

/+
int strcmpD2(S)(in S lhs, in S rhs) if(is(S == string) || is(S == 
const(char)[])) { // Breaks

return strcmp(
toStringz(lhs),
toStringz(rhs)
);
}
+/

void main(){
import std.stdio;
writeln(strcmpD0("foo", "bar")); // Best
writeln(strcmpD1("foo", "bar")); // Works
//writeln(strcmpD2("foo", "bar")); // Breaks
}




what's the right way to get char* from string?

2016-05-05 Thread aki via Digitalmars-d-learn

Hello,

When I need to call C function, often need to
have char* pointer from string.

"Interfacing to C++" page:
https://dlang.org/spec/cpp_interface.html
have following example.

extern (C) int strcmp(char* string1, char* string2);
import std.string;
int myDfunction(char[] s)
{
return strcmp(std.string.toStringz(s), "foo");
}

but this is incorrect because toStringz() returns immutable 
pointer.

One way is to write mutable version of toStringz()

char* toStringzMutable(string s) @trusted pure nothrow {
auto copy = new char[s.length + 1];
copy[0..s.length] = s[];
copy[s.length] = 0;
return copy.ptr;
}

But I think this is common needs,
why it is not provided by Phobos?
(or tell me if it has)

Thanks,
aki



Re: can't zip a char[5], string[5], real[5]

2015-10-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, October 21, 2015 14:11:20 anonymous via Digitalmars-d-learn wrote:
> On Wednesday, 21 October 2015 at 14:06:54 UTC, Shriramana Sharma
> wrote:
> > import std.stdio, std.range;
> > void mywrite(char [5] chars, real[5] vals)
> > {
> > static string [5] fmts = ["%9.4f, ", "%9.4f; ", "%3d, ",
> > "%3d, ",
> > "%3d\n"];
> > foreach (e; zip(chars, fmts, vals)) write(e[0], " = ",
> > e[1].format(e[2]));
> > }
> >
> > Compiling gives:
> [...]
> > I would have thought there would be no problem in creating a
> > zip of three arrays of equal length. What's the problem here?
>
> Static arrays are not ranges. You can't popFront them. Try
> slicing them: chars[], fmts[], vals[]

Though when you do that, be careful that you don't keep the dynamic arrays
(or any other ranges created from them) around longer than the static
arrays; otherwise, the dynamic arrays will then be referring to invalid
memory, and nasty things will happen...

But as long as the dynamic arrays don't exist longer than the static ones
that they refer to, then you're fine.

- Jonathan M Davis



Re: can't zip a char[5], string[5], real[5]

2015-10-21 Thread anonymous via Digitalmars-d-learn
On Wednesday, 21 October 2015 at 14:06:54 UTC, Shriramana Sharma 
wrote:

import std.stdio, std.range;
void mywrite(char [5] chars, real[5] vals)
{
static string [5] fmts = ["%9.4f, ", "%9.4f; ", "%3d, ", 
"%3d, ",

"%3d\n"];
foreach (e; zip(chars, fmts, vals)) write(e[0], " = ",
e[1].format(e[2]));
}

Compiling gives:

[...]
I would have thought there would be no problem in creating a 
zip of three arrays of equal length. What's the problem here?


Static arrays are not ranges. You can't popFront them. Try 
slicing them: chars[], fmts[], vals[]


can't zip a char[5], string[5], real[5]

2015-10-21 Thread Shriramana Sharma via Digitalmars-d-learn
import std.stdio, std.range;
void mywrite(char [5] chars, real[5] vals)
{
static string [5] fmts = ["%9.4f, ", "%9.4f; ", "%3d, ", "%3d, ", 
"%3d\n"];
foreach (e; zip(chars, fmts, vals)) write(e[0], " = ", 
e[1].format(e[2]));
}

Compiling gives:

zip_string.d(5): Error: template std.range.zip cannot deduce function from 
argument types !()(char[5], string[5], real[5]), candidates are:
/usr/include/dmd/phobos/std/range/package.d(3678):
std.range.zip(Ranges...)(Ranges ranges) if (Ranges.length && allSatisfy!
(isInputRange, Ranges))
/usr/include/dmd/phobos/std/range/package.d(3711):
std.range.zip(Ranges...)(StoppingPolicy sp, Ranges ranges) if (Ranges.length 
&& allSatisfy!(isInputRange, Ranges))

I would have thought there would be no problem in creating a zip of three 
arrays of equal length. What's the problem here?

-- 
Shriramana Sharma, Penguin #395953


Re: cannot implicitly convert char[] to string

2015-08-15 Thread Ali Çehreli via Digitalmars-d-learn

On 08/15/2015 04:45 AM, cym13 wrote:

 On Saturday, 15 August 2015 at 11:34:01 UTC, cym13 wrote:
 On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
 I made a PR to phobos where I modified `std.format.format`.
 https://github.com/D-Programming-Language/phobos/pull/3528

 However the auto builder fails, with the error message:
 runnable/test23.d(1219): Error: cannot implicitly convert expression
 (format(s = %s, s)) of type char[] to string

 The line which fails is `p = std.string.format(s = %s, s);`

 I don't understand why I can't convert a char[] to string.

 I think it has to do with the fact that string is an alias to
 immutable(char)[]   and you can't implicitely cast an immutable to a
 regular variable.

That's actually correct (for reference types). As long as there is no 
indirection, a value type can be casted implicitly:


struct S
{
int i;
}

void main()
{
auto i = immutable(S)();
auto m = S();

m = i;// copied; fine
}

 I phrased it completely wrong, an example will be better :

  import std.stdio;

  void fun(immutable(int)[] i) {
  i.writeln();
  }

  void main() {
  int[] i = [42];
  fun(i);
  }

 Will not compile because there is no certainty that fun() won't
 change the array

Actually, that's the job of 'const'. Here, it is not fun's ability to 
mutate but the caller's. 'immutable' on a function interface means a 
requirement: The caller *must* provide immutable data so that the 
function can rely on it not being changed by anyone.


Ali



Re: cannot implicitly convert char[] to string

2015-08-15 Thread cym13 via Digitalmars-d-learn

On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


I think it has to do with the fact that string is an alias to   
immutable(char)[]   and you can't implicitely cast an immutable 
to a regular variable.


Re: cannot implicitly convert char[] to string

2015-08-15 Thread cym13 via Digitalmars-d-learn

On Saturday, 15 August 2015 at 11:34:01 UTC, cym13 wrote:

On Saturday, 15 August 2015 at 11:25:20 UTC, vladde wrote:
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


I think it has to do with the fact that string is an alias to   
immutable(char)[]   and you can't implicitely cast an immutable 
to a regular variable.


I phrased it completely wrong, an example will be better :

import std.stdio;

void fun(immutable(int)[] i) {
i.writeln();
}

void main() {
int[] i = [42];
fun(i);
}

Will not compile because there is no certainty that fun() won't
change the array while the following will work

import std.stdio;

void fun(immutable(int)[] i) {
i.writeln();
}

void main() {
int[] i = [42];
fun(i.dup);

immutable(int)[] j = [42];
fun(j);

immutable(int[]) k = [42];
fun(k);
}



Re: cannot implicitly convert char[] to string

2015-08-15 Thread Timon Gehr via Digitalmars-d-learn

On 08/15/2015 01:54 PM, Timon Gehr wrote:

On 08/15/2015 01:25 PM, vladde wrote:

I made a PR to phobos where I modified `std.format.format`.
https://github.com/D-Programming-Language/phobos/pull/3528

However the auto builder fails, with the error message:

runnable/test23.d(1219): Error: cannot implicitly convert expression
(format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Get rid of the 'in' in format's signature.


Oh, I see, this is by design (which I don't like, but OK.)
The reason the conversion does not go through is that format is not 
marked as pure.


Re: cannot implicitly convert char[] to string

2015-08-15 Thread Timon Gehr via Digitalmars-d-learn

On 08/15/2015 01:25 PM, vladde wrote:

I made a PR to phobos where I modified `std.format.format`.
https://github.com/D-Programming-Language/phobos/pull/3528

However the auto builder fails, with the error message:

runnable/test23.d(1219): Error: cannot implicitly convert expression
(format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Get rid of the 'in' in format's signature.


cannot implicitly convert char[] to string

2015-08-15 Thread vladde via Digitalmars-d-learn
I made a PR to phobos where I modified `std.format.format`. 
https://github.com/D-Programming-Language/phobos/pull/3528


However the auto builder fails, with the error message:
runnable/test23.d(1219): Error: cannot implicitly convert 
expression (format(s = %s, s)) of type char[] to string


The line which fails is `p = std.string.format(s = %s, s);`

I don't understand why I can't convert a char[] to string.


Re: Insert a char in string

2014-07-12 Thread Ali Çehreli via Digitalmars-d-learn

On 07/10/2014 09:05 AM, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I try to use
the array.insertInPlace, but, not work...

I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


Here is another solution, which does not modify the original string:

import std.stdio;
import std.algorithm;
import std.range;
import std.string;

void main()
{
auto number = 12345678;

auto formatted =
zip(number.retro, sequence!n + 1)
.map!(z = format(!(z[1] % 3) ? %s, : %s, z[0]))
.join
.retro;

assert(formatted.equal(12,345,678));
}

I am not happy with the .join there because I think it makes an array 
but I could not get it to compile with the lazy .joiner because I think 
it dose not look like a bidirectional range to .retro.


Ali



Re: Insert a char in string

2014-07-11 Thread JR via Digitalmars-d-learn

On Thursday, 10 July 2014 at 19:33:15 UTC, simendsjo wrote:

On 07/10/2014 06:05 PM, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use

the array.insertInPlace, but, not work...

I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


Do you really want to insert a comma in the string, or do you 
want to

format a number as 100,000,000,000.00?


For that, one approach would be as in 
http://dpaste.dzfl.pl/bddb71eb75bb.


Insert a char in string

2014-07-10 Thread Alexandre via Digitalmars-d-learn

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I try 
to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


Re: Insert a char in string

2014-07-10 Thread John Colvin via Digitalmars-d-learn

On Thursday, 10 July 2014 at 16:05:51 UTC, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


insertInPlace works like this:

auto X = 100;
auto X1 = X;
X.insertInPlace(3, ',');
assert(X == 100,);
assert(X1 == 100);


You can also do this:

auto X = 100;
auto N = X[0 .. 3] ~ ',' ~ X[3 .. $];
assert(X == 100);
assert(N == 100,);


Re: Insert a char in string

2014-07-10 Thread Alexandre via Digitalmars-d-learn

Sorry..
I mean:

auto X = 100;
auto N = X.insertInPlace(3,',');

On Thursday, 10 July 2014 at 16:05:51 UTC, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');




Re: Insert a char in string

2014-07-10 Thread Alexandre via Digitalmars-d-learn

I used that solution:

string InsertComma(string val)
{
return val[0 .. $-2] ~ , ~ val[$-2 .. $];
}

On Thursday, 10 July 2014 at 16:23:44 UTC, John Colvin wrote:

On Thursday, 10 July 2014 at 16:05:51 UTC, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


insertInPlace works like this:

auto X = 100;
auto X1 = X;
X.insertInPlace(3, ',');
assert(X == 100,);
assert(X1 == 100);


You can also do this:

auto X = 100;
auto N = X[0 .. 3] ~ ',' ~ X[3 .. $];
assert(X == 100);
assert(N == 100,);




Re: Insert a char in string

2014-07-10 Thread via Digitalmars-d-learn

On Thursday, 10 July 2014 at 16:20:29 UTC, Alexandre wrote:

Sorry..
I mean:

auto X = 100;
auto N = X.insertInPlace(3,',');

On Thursday, 10 July 2014 at 16:05:51 UTC, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


`std.array.insertInPlace` doesn't return anything. In place 
here means in situ, i.e. it will not create a new string, but 
insert the new elements into the existing one. This operation may 
still reallocate, in which case the array slice you're passing in 
will be updated to point to the new memory.


Either use this instead:

auto x = 100;
auto n = x.dup;
n.insertInPlace(3, ',');
// or: insertInPlace(n, 3, ',');

... or use slicing and concatenating to construct a new string:

auto g = x[0 .. 3] ~ ',' ~ x[3 .. $];

(Side note about style: It's common practice to use lower-case 
names for variables, upper-case first letters are used to denote 
types. But of course, that's a matter of taste.)


Re: Insert a char in string

2014-07-10 Thread Alexandre via Digitalmars-d-learn

Oh, I used that letters in upper case, just for a simple sample...

On Thursday, 10 July 2014 at 16:32:53 UTC, Marc Schütz wrote:

On Thursday, 10 July 2014 at 16:20:29 UTC, Alexandre wrote:

Sorry..
I mean:

auto X = 100;
auto N = X.insertInPlace(3,',');

On Thursday, 10 July 2014 at 16:05:51 UTC, Alexandre wrote:
I have a string X and I need to insert a char in that 
string...


auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use the array.insertInPlace, but, not work...


I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


`std.array.insertInPlace` doesn't return anything. In place 
here means in situ, i.e. it will not create a new string, but 
insert the new elements into the existing one. This operation 
may still reallocate, in which case the array slice you're 
passing in will be updated to point to the new memory.


Either use this instead:

auto x = 100;
auto n = x.dup;
n.insertInPlace(3, ',');
// or: insertInPlace(n, 3, ',');

... or use slicing and concatenating to construct a new string:

auto g = x[0 .. 3] ~ ',' ~ x[3 .. $];

(Side note about style: It's common practice to use lower-case 
names for variables, upper-case first letters are used to 
denote types. But of course, that's a matter of taste.)




Re: Insert a char in string

2014-07-10 Thread simendsjo via Digitalmars-d-learn
On 07/10/2014 06:05 PM, Alexandre wrote:
 I have a string X and I need to insert a char in that string...
 
 auto X = 100;
 
 And I need to inser a ',' in position 3 of this string..., I try to use
 the array.insertInPlace, but, not work...
 
 I try this:
 auto X = 100;
 auto N = X.insertInPlace(1,'0');

Do you really want to insert a comma in the string, or do you want to
format a number as 100,000,000,000.00?


Re: Insert a char in string

2014-07-10 Thread Alexandre via Digitalmars-d-learn

basically format
I read a cobol struct file...

From pos X to Y I have a money value... but, this value don't 
have any format..


0041415

The 15 is the cents... bascally I need to put the ( comma ), we 
use comma to separate the cents, here in Brazil...


On Thursday, 10 July 2014 at 19:33:15 UTC, simendsjo wrote:

On 07/10/2014 06:05 PM, Alexandre wrote:

I have a string X and I need to insert a char in that string...

auto X = 100;

And I need to inser a ',' in position 3 of this string..., I 
try to use

the array.insertInPlace, but, not work...

I try this:
auto X = 100;
auto N = X.insertInPlace(1,'0');


Do you really want to insert a comma in the string, or do you 
want to

format a number as 100,000,000,000.00?




Re: Insert a char in string

2014-07-10 Thread simendsjo via Digitalmars-d-learn
On 07/10/2014 09:58 PM, Alexandre wrote:
 basically format
 I read a cobol struct file...
 
 From pos X to Y I have a money value... but, this value don't have any
 format..
 
 0041415
 
 The 15 is the cents... bascally I need to put the ( comma ), we use
 comma to separate the cents, here in Brazil...
 
 On Thursday, 10 July 2014 at 19:33:15 UTC, simendsjo wrote:
 On 07/10/2014 06:05 PM, Alexandre wrote:
 I have a string X and I need to insert a char in that string...

 auto X = 100;

 And I need to inser a ',' in position 3 of this string..., I try to use
 the array.insertInPlace, but, not work...

 I try this:
 auto X = 100;
 auto N = X.insertInPlace(1,'0');

 Do you really want to insert a comma in the string, or do you want to
 format a number as 100,000,000,000.00?
 

I'm not sure what you're trying to do though.
Do you need to fix the file by adding a comma at appropriate places? Or
read it into D and write it to the console with your currency format?
This is one way of reading in the values using slices and std.conv:

import std.stdio, std.conv;
void main() {
immutable input = 0041415;
double amount = input[0..$-2].to!double();
amount += input[$-2..$].to!double() / 100;
writeln(amount);
}



Re: Modify char in string

2014-05-19 Thread Tim via Digitalmars-d-learn

On Sunday, 18 May 2014 at 19:09:52 UTC, Chris Cain wrote:

On Sunday, 18 May 2014 at 18:55:59 UTC, Tim wrote:

Hi everyone,

is there any chance to modify a char in a string like:


As you've seen, you cannot modify immutables (string is an 
immutable(char)[]). If you actually do want the string to be 
modifiable, you should define it as char[] instead.


Then your example will work:

void main()
{
   char[] sMyText = Replace the last char_;
   sMyText[$ - 1] = '.';
}

If you actually want it to be immutable, you can still do it, 
but you can't modify in-place, you must create a new string 
that looks like what you want:


void main()
{
   string sMyText = Replace the last char_;
   sMyText = sMyText[0 .. $-1] ~ .;
   // you would do
   //sMyText[0 .. 5] ~ . ~ sMyText[6..$];
   // to replace something in the 5th position
}

Note that the second method allocates and uses the GC more 
(which is perfectly fine, but not something you want to do in a 
tight loop). For most circumstances, the second method is good.


Thanks - I already tried:

 void main()
 {
char[] sMyText = Replace the last char_;
sMyText[$ - 1] = '.';
 }

but I always getting Error: cannot implicitly convert expression 
(Replace the last char_) of type string to char[]. I know, I 
can use cast(char[]) but I don't like casts for such simple 
things...


Re: Modify char in string

2014-05-19 Thread Ali Çehreli via Digitalmars-d-learn

On 05/19/2014 10:07 AM, Tim wrote:

 I already tried:

   void main()
   {
  char[] sMyText = Replace the last char_;
  sMyText[$ - 1] = '.';
   }

 but I always getting Error: cannot implicitly convert expression
 (Replace the last char_) of type string to char[].

That's a good thing because that string literal is immutable. If that 
code compiled you would get undefined behavior.


 I know, I can use cast(char[])

Unfortunately, not in this case. That undefined behavior would manifest 
itself as a Segmentation fault on many systems. :)


 but I don't like casts for such simple things...

What you want to do makes sense only if you have a mutable ASCII string. 
Such strings are generated at run time so the problem is usually a non 
issue:


import std.stdio;

void main()
{
foreach (line; stdin.byLine) {
char[] s = line.dup;// (or .idup if you want immutable)
s[$-1] = '.';
writefln(Input : %s, line);
writefln(Output: %s, s);
}
}

Ali



Modify char in string

2014-05-18 Thread Tim via Digitalmars-d-learn

Hi everyone,

is there any chance to modify a char in a string like:

void main()
{
   string sMyText = Replace the last char_;
   sMyText[$ - 1] = '.';
}

But when I execute the code above I'm always getting cannot 
modify immutable expression at sMyText[__dollar -1LU]. I though 
D supported such modifications anytime. How can I do that now...?


Re: Modify char in string

2014-05-18 Thread bearophile via Digitalmars-d-learn

Tim:


is there any chance to modify a char in a string like:

void main()
{
   string sMyText = Replace the last char_;
   sMyText[$ - 1] = '.';
}

But when I execute the code above I'm always getting cannot 
modify immutable expression at sMyText[__dollar -1LU]. I 
though D supported such modifications anytime. How can I do 
that now...?


D strings are immutable. And mutating immutable variables is a 
bug in D. So you can't do that. You have to work around the 
problem. One solution is to not have a string, but something more 
like a char[] in the first place, and mutate it.


If you have a string, you can do (this works with the current GIT 
DMD compiler):




/// Not Unicode-safe.
string dotLast(in string s) pure nothrow {
auto ds = s.dup;
ds[$ - 1] = '.';
return ds;
}

void main() {
import std.stdio;

immutable input = Replace the last char_;
immutable result = input.dotLast;
result.writeln;
}


That code doesn't work if your text contains more than the Ascii 
chars.


Bye,
bearophile


Re: Modify char in string

2014-05-18 Thread Chris Cain via Digitalmars-d-learn

On Sunday, 18 May 2014 at 18:55:59 UTC, Tim wrote:

Hi everyone,

is there any chance to modify a char in a string like:


As you've seen, you cannot modify immutables (string is an 
immutable(char)[]). If you actually do want the string to be 
modifiable, you should define it as char[] instead.


Then your example will work:

void main()
{
   char[] sMyText = Replace the last char_;
   sMyText[$ - 1] = '.';
}

If you actually want it to be immutable, you can still do it, but 
you can't modify in-place, you must create a new string that 
looks like what you want:


void main()
{
   string sMyText = Replace the last char_;
   sMyText = sMyText[0 .. $-1] ~ .;
   // you would do
   //sMyText[0 .. 5] ~ . ~ sMyText[6..$];
   // to replace something in the 5th position
}

Note that the second method allocates and uses the GC more (which 
is perfectly fine, but not something you want to do in a tight 
loop). For most circumstances, the second method is good.


Does anybody have an example of overloading a function to accept char[] or string parameter

2014-03-30 Thread Gary Miller


In a lot of my string manipulation functions I need the 
flexibility of passing a string but other times I need to pass a 
char[] so that I can change the contents of the string in the 
function.  Because the string data type is immutable I get errors 
if I pass it as a parameter and try to change it in the function.


Can I overload a function to work for either a char[] or a string?

Many of the library functions that I need to call require string 
arguments such as the replace below.


I believe I can create a wrapper function for it like this to 
still get at the functionality. But this seems like a lot of work 
for every function.


I'm almost sorry that the the string datatype was created because 
then probably all the library string handling would have been 
written for char[].


Are there any alternate libraries for D that have a mutable 
string datatype or is there a way to override the immutable 
characteristic of the string datatype by reallocating it or 
something?


I realize that the reduced memory reallocation in string handling 
is probably a major reason that D is faster than other more 
dynamic languages like Python but


Maybe the functions in std.string could be overloaded into a 
std.mutablestring library at some point to eliminate emulate the 
functionality of more dynamic languages for those programs that 
need it.


char[] ReplaceAllSubstrings(inout char[] Original,
in char[] SearchString,
in char[] Substring)
{
string SOriginal = Original.dup;
string SSearchString = SearchString.dup;
string SSubstring = Substring.dup;
SOriginal.replace(SSearchString, SSubstring);
return Original.dup;
}





Re: Does anybody have an example of overloading a function to accept char[] or string parameter

2014-03-30 Thread evilrat

On Sunday, 30 March 2014 at 15:58:52 UTC, Gary Miller wrote:

Are there any alternate libraries for D that have a mutable 
string datatype or is there a way to override the immutable 
characteristic of the string datatype by reallocating it or 
something?


string.dup property does a copy of original array(! note that 
this is array property and would work for any other arrays and 
slices).


you can have overloaded variant for strings but i think compiler 
would optimize to call everything as string variant, you can 
figure this out on your own.


Re: Does anybody have an example of overloading a function to accept char[] or string parameter

2014-03-30 Thread bearophile

Gary Miller:


char[] ReplaceAllSubstrings(inout char[] Original,
in char[] SearchString,
in char[] Substring)
{
string SOriginal = Original.dup;
string SSearchString = SearchString.dup;
string SSubstring = Substring.dup;
SOriginal.replace(SSearchString, SSubstring);
return Original.dup;
}


Here if you care for some efficiency you need to dup only 
SOriginal. And at the end you can call assumeUnique if you want 
to return a string (or you can use a less efficient idup).


Note that in D string/function names start with a lowercase.

It's also better to use auto instead of string in that 
function, because the result of dup is not a string.


Bye,
bearophile


[Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread Mark Isaacson


I am presently working my way through TDPL for the second time, 
and there's an example in chapter 1 to the effect of:


[code]
string currentParagraph;
foreach(line; stdin.byLine()) {
  if (line.length  2) {
currentParagraph = to!string(line[2 .. $]);
  }
}
[/code]

The explicit conversion is necessary because `line` is a `char[]` 
but `currentParagraph` is a `string`. My question is why use 
`to!string` instead of just doing `line[2 .. $].idup`?


Is there a performance benefit? Is it simply because it's more 
general?


I tried taking a peek at the implementation of to!string, but it 
wasn't easy enough to follow and boil down into components.


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread Justin Whear
On Tue, 25 Mar 2014 21:35:46 +, Mark Isaacson wrote:

 I am presently working my way through TDPL for the second time, and
 there's an example in chapter 1 to the effect of:
 
 [code]
 string currentParagraph;
 foreach(line; stdin.byLine()) {
if (line.length  2) {
  currentParagraph = to!string(line[2 .. $]);
}
 }
 [/code]
 
 The explicit conversion is necessary because `line` is a `char[]`
 but `currentParagraph` is a `string`. My question is why use `to!string`
 instead of just doing `line[2 .. $].idup`?
 
 Is there a performance benefit? Is it simply because it's more general?
 
 I tried taking a peek at the implementation of to!string, but it wasn't
 easy enough to follow and boil down into components.

I believe char[] - string conversion with to! will use this 
implementation: https://github.com/D-Programming-Language/phobos/blob/
master/std/conv.d#L823

So there should be no performance implications, but to!string is better 
self-documenting and flexible should you need to change the input type in 
future.


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread bearophile

Mark Isaacson:


why use `to!string` instead of just doing `line[2 .. $].idup`?


I sometimes prefer the text function:

 = line[2 .. $].text;

Bye,
bearophile


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread monarch_dodra

On Tuesday, 25 March 2014 at 21:35:47 UTC, Mark Isaacson wrote:
Is there a performance benefit? Is it simply because it's more 
general?


Mostly because it's more generic. For example:
If instead you want to do string = char[], then your code 
will have to be changed to use dup.
if instead you want to do char[] = dstring, then your code will 
simply not work at all.


By contrast, to! will just work. It's A one-stop shop for 
converting values from one type to another.


There is *1* thing you should take into account though: to! is 
a no-op for string=string or char[]=char[], or anything else 
that can be implicitly converted as such. In contrast, 
dup/idup will create an actual copy.


Not that this is good or bad. Just something you should keep in 
mind.


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread Mark Isaacson
Much appreciated everyone! I had a vague intuition that these 
were the reasons, but it was helpful to spell them out. I'm 
especially partial to the self-documentation reasoning.


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread H. S. Teoh
On Tue, Mar 25, 2014 at 10:02:33PM +, monarch_dodra wrote:
 On Tuesday, 25 March 2014 at 21:35:47 UTC, Mark Isaacson wrote:
 Is there a performance benefit? Is it simply because it's more general?
[...]
 There is *1* thing you should take into account though: to! is a
 no-op for string=string or char[]=char[], or anything else that can
 be implicitly converted as such. In contrast, dup/idup will create
 an actual copy.
 
 Not that this is good or bad. Just something you should keep in mind.

I think it's a good thing. It avoids needless copying where it's not
necessary. (Of course, if you have a char[] and you actually want a new
copy, then you have to use .dup explicitly.)


T

-- 
Маленькие детки - маленькие бедки.


Re: [Style] Converting from char[] to string, to!string vs idup

2014-03-25 Thread Steven Schveighoffer
On Tue, 25 Mar 2014 19:13:07 -0400, H. S. Teoh hst...@quickfur.ath.cx  
wrote:



On Tue, Mar 25, 2014 at 10:02:33PM +, monarch_dodra wrote:

On Tuesday, 25 March 2014 at 21:35:47 UTC, Mark Isaacson wrote:
Is there a performance benefit? Is it simply because it's more general?

[...]

There is *1* thing you should take into account though: to! is a
no-op for string=string or char[]=char[], or anything else that can
be implicitly converted as such. In contrast, dup/idup will create
an actual copy.

Not that this is good or bad. Just something you should keep in mind.


I think it's a good thing. It avoids needless copying where it's not
necessary. (Of course, if you have a char[] and you actually want a new
copy, then you have to use .dup explicitly.)


In the case of char[] - char[], you explicitly want to dup. The original  
text is part of a buffer that is reused.


-Steve


Re: How to handle char* to string from C functions?

2014-01-02 Thread Gary Willoughby

On Wednesday, 1 January 2014 at 23:09:05 UTC, Adam D. Ruppe wrote:
On Wednesday, 1 January 2014 at 23:03:06 UTC, Gary Willoughby 
wrote:
I'm calling an external C function which returns a string 
delivered via a char*. When i print this string out, like this:


char* result = func();'


you can then do

string r = to!string(result);

or

char[] r = result[0 .. strlen(result)];


and use that/


to!(string) works great thanks!


Re: How to handle char* to string from C functions?

2014-01-02 Thread Gary Willoughby

On Wednesday, 1 January 2014 at 23:09:05 UTC, Adam D. Ruppe wrote:
On Wednesday, 1 January 2014 at 23:03:06 UTC, Gary Willoughby 
wrote:
I'm calling an external C function which returns a string 
delivered via a char*. When i print this string out, like this:


char* result = func();'


you can then do

string r = to!string(result);

or

char[] r = result[0 .. strlen(result)];


and use that/


Another question: how do i convert const(char)** to string[]?


Re: How to handle char* to string from C functions?

2014-01-02 Thread bearophile

Gary Willoughby:


Another question: how do i convert const(char)** to string[]?


If you know that you have N strings, then a solution is 
(untested):


pp[0 .. N].map!text.array

If it doesn't work, try:

pp[0 .. N].map!(to!string).array

Bye,
bearophile


Re: How to handle char* to string from C functions?

2014-01-02 Thread uc
You are going to need the length of your c char*[] then a 
for-loop should do it :D


Re: How to handle char* to string from C functions?

2014-01-02 Thread Adam D. Ruppe

On Thursday, 2 January 2014 at 15:31:25 UTC, bearophile wrote:
If you know that you have N strings, then a solution is 
(untested):


Or if it is zero terminated, maybe

pp.until!a is null.map!text.array


Though personally I'd just use the plain old for loop.


Re: How to handle char* to string from C functions?

2014-01-02 Thread monarch_dodra

On Thursday, 2 January 2014 at 15:53:40 UTC, Adam D. Ruppe wrote:

On Thursday, 2 January 2014 at 15:31:25 UTC, bearophile wrote:
If you know that you have N strings, then a solution is 
(untested):


Or if it is zero terminated, maybe

pp.until!a is null.map!text.array


Though personally I'd just use the plain old for loop.


0-terminated arrays of non-strings :puke:


Re: How to handle char* to string from C functions?

2014-01-02 Thread Gary Willoughby

On Thursday, 2 January 2014 at 15:31:25 UTC, bearophile wrote:

Gary Willoughby:


Another question: how do i convert const(char)** to string[]?


If you know that you have N strings, then a solution is 
(untested):


pp[0 .. N].map!text.array

If it doesn't work, try:

pp[0 .. N].map!(to!string).array

Bye,
bearophile


Thanks, both work well:

I've noticed that const(char)** can be accessed via indexes:

writefln(%s, pp[0].to!(string)); //etc.

cool!


Re: How to handle char* to string from C functions?

2014-01-02 Thread uc

i'll answer in code
http://dpaste.dzfl.pl/2bb1a1a8


Re: How to handle char* to string from C functions?

2014-01-02 Thread bearophile

Gary Willoughby:


I've noticed that const(char)** can be accessed via indexes:

writefln(%s, pp[0].to!(string)); //etc.

cool!


This is a feature that works with all pointers to a sequence of 
items, like in C. But array bounds are not verified, so it's more 
bug-prone. So if you know the length it's better to slice the 
pointer as soon as possible, and then use the slice:


auto ap = pp[0 .. N];
writefln(%s, ap[0].text);

Or just:

printf(%s\n, ap[0]);

Bye,
bearophile


How to handle char* to string from C functions?

2014-01-01 Thread Gary Willoughby
I'm calling an external C function which returns a string 
delivered via a char*. When i print this string out, like this:


char* result = func();

writefln(String: %s, *result);

I only get one character printed. I guess this is expected 
because i'm only returned a pointer to the first char. Instead of 
incrementing the pointer until i reach a null is there an easy 
way to convert this to a D string or get writeln to print the 
entire char array?


Re: How to handle char* to string from C functions?

2014-01-01 Thread Adam D. Ruppe
On Wednesday, 1 January 2014 at 23:03:06 UTC, Gary Willoughby 
wrote:
I'm calling an external C function which returns a string 
delivered via a char*. When i print this string out, like this:


char* result = func();'


you can then do

string r = to!string(result);

or

char[] r = result[0 .. strlen(result)];


and use that/


Re: How to handle char* to string from C functions?

2014-01-01 Thread John Colvin
On Wednesday, 1 January 2014 at 23:03:06 UTC, Gary Willoughby 
wrote:
I'm calling an external C function which returns a string 
delivered via a char*. When i print this string out, like this:


char* result = func();

writefln(String: %s, *result);

I only get one character printed.


You're not asking to print the string, by dereferencing the 
pointer you're literally asking to print the first character.


If you don't want to have to walk the length of the the string to 
make the D array equivalent, you could always wrap it in a 
forward range to emulate c string handling.


Re: Cannot cast char[] to string.

2013-11-14 Thread Dicebot

On Thursday, 14 November 2013 at 19:41:13 UTC, Agustin wrote:
I'm trying to use http://dlang.org/phobos/std_net_curl.html and 
when i compile the same example i get:


cannot implicitly convert expression 
(get(cast(const(char)[])address, AutoProtocol())) of type 
char[] to string


string address = http://dlang.org;;
string _data = get(address);


`get` returns mutable data, one should respect it:

char[] data = get(address); // or just use `auto data = `


Cannot cast char[] to string.

2013-11-14 Thread Agustin
I'm trying to use http://dlang.org/phobos/std_net_curl.html and 
when i compile the same example i get:


cannot implicitly convert expression 
(get(cast(const(char)[])address, AutoProtocol())) of type char[] 
to string


string address = http://dlang.org;;
string _data = get(address);


Re: Cannot cast char[] to string.

2013-11-14 Thread Brad Anderson

On Thursday, 14 November 2013 at 19:41:13 UTC, Agustin wrote:
I'm trying to use http://dlang.org/phobos/std_net_curl.html and 
when i compile the same example i get:


cannot implicitly convert expression 
(get(cast(const(char)[])address, AutoProtocol())) of type 
char[] to string


string address = http://dlang.org;;
string _data = get(address);


You have two options:

string address = http://dlang.org;;
string _data = get(address).idup(); // create immutable copy

or

string address = http://dlang.org;;
char[] _data = get(address); // store mutable reference

A string (which is just an alias of immutable(char)[]) can't be 
made from a char[] without an assertion that the data pointed to 
is, in fact, immutable.  You can do that using assumeUnique 
(inexplicably found in std.exception).


Re: Cannot cast char[] to string.

2013-11-14 Thread Ali Çehreli

On 11/14/2013 11:43 AM, Dicebot wrote:

On Thursday, 14 November 2013 at 19:41:13 UTC, Agustin wrote:

I'm trying to use http://dlang.org/phobos/std_net_curl.html and when i
compile the same example i get:

cannot implicitly convert expression (get(cast(const(char)[])address,
AutoProtocol())) of type char[] to string

string address = http://dlang.org;;
string _data = get(address);


`get` returns mutable data, one should respect it:

char[] data = get(address); // or just use `auto data = `


However, that data can automatically be converted to string if get() 
were pure. (I can understand how such a function cannot be.)


A simple wrapper:

import std.net.curl;
import std.exception;

string getAsString(string address)
{
auto result = get(address);
return assumeUnique(result);
}

void main()
{
string content = getAsString(dlang.org);
}

Ali



Re: Cannot cast char[] to string.

2013-11-14 Thread Jonathan M Davis
On Thursday, November 14, 2013 20:45:55 Brad Anderson wrote:
 On Thursday, 14 November 2013 at 19:41:13 UTC, Agustin wrote:
  I'm trying to use http://dlang.org/phobos/std_net_curl.html and
  when i compile the same example i get:
  
  cannot implicitly convert expression
  (get(cast(const(char)[])address, AutoProtocol())) of type
  char[] to string
  
  string address = http://dlang.org;;
  string _data = get(address);
 
 You have two options:
 
 string address = http://dlang.org;;
 string _data = get(address).idup(); // create immutable copy
 
 or
 
 string address = http://dlang.org;;
 char[] _data = get(address); // store mutable reference

If you want a string rather than char[], it's probably better to use 
std.conv.to. In the case of char[], it'll just end up calling idup for you, 
but if you use to!string(arr) as the normal means for converting arrays of 
characters to string, then you don't have to worry about the constness of the 
array, and if it turns out that the array was in fact string (which is quite 
easy to have happen if you're dealing with generic code), then it'll avoid 
iduping the array and will simply return it.

 A string (which is just an alias of immutable(char)[]) can't be
 made from a char[] without an assertion that the data pointed to
 is, in fact, immutable. You can do that using assumeUnique
 (inexplicably found in std.exception).

AFAIK, there is no way to make such an assertion. assumeUnique simply casts to 
immutable (though it will set the array passed in to null if you pass it an 
lvalue). So, it's completely up to the programmer to guarantee that the array 
is indeed unique. The primary used case for it is if you have to construct an 
array which you need to be immutable, and you need it to be mutable while 
you're setting all of its elements, in which case, you use assumeUnique on the 
array after you've set all of its elements, and you make sure that you don't 
have any other references to the array when you do that. If that's not what 
you're doing, you probably shouldn't be using assumeUnique. Certainly, using 
it on the result of a function that returns char[] is almost certainly wrong, 
and could result in very weird behavior, because the compiler is free to 
optimize based on the fact that the array is immutable, and if there's a 
mutable reference to that array, then you've subverted the type system, and 
ruined the compilers guarantees.

- Jonathan M Davis


Issue with char and string overlap

2013-07-19 Thread JS
I'm trying to create a split function that can handle both char 
and string delims. I initially created two separate functions but 
this doesn't work for default parameters since the compiler 
doesn't know which one to choose(but in this case both would work 
fine and it would be nice to inform the compiler of that). I then 
tried to template and conditionally code the two but it still 
doesn't work:


both functions work separately but when i uncomment the string 
version I get an error about the string version shadowing.


import std.stdio, std.cstream;

string[] split(T)(string s, T d) if (is(T == char) || is(T == 
string))

{
int i = 0, oldj = 0; bool ok = true;
string[] r;
foreach(j, c; s)
{
static if (is(T == char))
{
if (c == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j];
i++; oldj = j+1;
ok = false;
} else if (!ok) ok = true;
}
else if (is(T == string))
{
/*
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (i == r.length) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
*/
}
}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}


string[] splitS(string s, string d =  )
{
int i = 0, oldj = 0; bool ok = true;
string[] r;
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}

r.length = i;
return r;
}

void main(string[] args)
{

auto s = splitS(abc bas   ccc,  );

foreach(a; s) writeln(a);

din.getc();
}


Re: Issue with char and string overlap

2013-07-19 Thread JS

On Friday, 19 July 2013 at 17:18:00 UTC, JS wrote:
I'm trying to create a split function that can handle both char 
and string delims. I initially created two separate functions 
but this doesn't work for default parameters since the compiler 
doesn't know which one to choose(but in this case both would 
work fine and it would be nice to inform the compiler of that). 
I then tried to template and conditionally code the two but it 
still doesn't work:


both functions work separately but when i uncomment the string 
version I get an error about the string version shadowing.


import std.stdio, std.cstream;

string[] split(T)(string s, T d) if (is(T == char) || is(T == 
string))

{
int i = 0, oldj = 0; bool ok = true;
string[] r;
foreach(j, c; s)
{
static if (is(T == char))
{
if (c == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j];
i++; oldj = j+1;
ok = false;
} else if (!ok) ok = true;
}
else if (is(T == string))
{
/*
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (i == r.length) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
*/
}
}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}


string[] splitS(string s, string d =  )
{
int i = 0, oldj = 0; bool ok = true;
string[] r;
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}

r.length = i;
return r;
}

void main(string[] args)
{

auto s = splitS(abc bas   ccc,  );

foreach(a; s) writeln(a);

din.getc();
}


BTW, I'd like to have a default value for d. That or efficiently
allow for variadic d, which then the default delim could easily
be tested for.


Re: Issue with char and string overlap

2013-07-19 Thread monarch_dodra

On Friday, 19 July 2013 at 17:18:00 UTC, JS wrote:
I'm trying to create a split function that can handle both char 
and string delims. I initially created two separate functions 
but this doesn't work for default parameters since the compiler 
doesn't know which one to choose(but in this case both would 
work fine and it would be nice to inform the compiler of that).


Simply provide a default parameter for *one* of the functions. EG:
string[] split(string s, char d = ' ');
string[] split(string s, string d);

This lifts the ambiguity. If *both* have default params, then the
ambiguity is simply not solvable, even by a human being.

Another solution is the no default multiple sig option, eg:
string[] split(string s)
{
 return split(s, ' ');
}
string[] split(string s, char d);
string[] split(string s, string d);

PS: Are you doing this to learn? std.array.split does the same
thing for you.

I then tried to template and conditionally code the two but it 
still doesn't work:


both functions work separately but when i uncomment the string 
version I get an error about the string version shadowing.


import std.stdio, std.cstream;

string[] split(T)(string s, T d) if (is(T == char) || is(T == 
string))

{
int i = 0, oldj = 0; bool ok = true;
string[] r;
foreach(j, c; s)
{
static if (is(T == char))
{
if (c == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j];
i++; oldj = j+1;
ok = false;
} else if (!ok) ok = true;
}
else if (is(T == string))
{
/*
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (i == r.length) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
*/
}
}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}


string[] splitS(string s, string d =  )
{
int i = 0, oldj = 0; bool ok = true;
string[] r;
for(int j = 0; j  s.length - d.length; j++)
{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}

r.length = i;
return r;
}

void main(string[] args)
{

auto s = splitS(abc bas   ccc,  );

foreach(a; s) writeln(a);

din.getc();
}


Re: Issue with char and string overlap

2013-07-19 Thread Ali Çehreli

On 07/19/2013 10:40 AM, anonymous wrote:

 On Friday, 19 July 2013 at 17:18:00 UTC, JS wrote:

 for(int j = 0; j  s.length - d.length; j++)

 This j would shadow the one above. Just choose another name.

Even better:

foreach (k; 0 .. s.length - d.length)

or:

foreach (k; iota(s.length - d.length))

Also, either code must deal with the case where d.length is greater than 
s.length. Otherwise, being a size_t, the subtraction will be a large value.


Ali



Re: Issue with char and string overlap

2013-07-19 Thread H. S. Teoh
On Fri, Jul 19, 2013 at 07:17:57PM +0200, JS wrote:
[...]
 string[] split(T)(string s, T d) if (is(T == char) || is(T ==
 string))
 {
   int i = 0, oldj = 0; bool ok = true;
   string[] r;
   foreach(j, c; s)
   {
   static if (is(T == char))
   {
   if (c == d)
   {
   if (!ok) { oldj++; continue; }
   if (r.length = i) r.length += 5;
   r[i] = s[oldj..j];
   i++; oldj = j+1;
   ok = false;
   } else if (!ok) ok = true;
   }
   else if (is(T == string))

 ^^
 This should be else static if, otherwise it will
 probably not do what you expect. :)


T

-- 
There are two ways to write error-free programs; only the third one works.


Re: Issue with char and string overlap

2013-07-19 Thread monarch_dodra

On Friday, 19 July 2013 at 17:25:34 UTC, JS wrote:

BTW, I'd like to have a default value for d. That or efficiently
allow for variadic d, which then the default delim could easily
be tested for.


To answer your previous question about shadowing, you are
probably experiencing an old bug where you can't overload a
template and non-template. This was fixed in HEAD, but is not yet
available in a packaged version (eg, it is not in 2.063.2).

The standard workaround is declaring your function as a
parameter-less parameterized function (!)

string[] split()(string s, string d); //This is actually a
template.

If you want d to be variadic, while still having a default case,
any number of solutions are available, including simply doing
this:

string[] split()(string s); (1*)
string[] split(Args...)(string s, Args args); (2)

(1) is more specialized (I think), so will be considered the
better match for split(hello). IF I'm wrong, simply add if
(Args.length  0) as a template restriction for the second
function, and you are good to go.

If you have access to head, then declare (1) as a straight up
function. In that case, it most certainly *will* be the better
match.


Re: Issue with char and string overlap

2013-07-19 Thread anonymous

On Friday, 19 July 2013 at 17:18:00 UTC, JS wrote:
both functions work separately but when i uncomment the string 
version I get an error about the string version shadowing.


import std.stdio, std.cstream;

string[] split(T)(string s, T d) if (is(T == char) || is(T == 
string))

{
int i = 0, oldj = 0; bool ok = true;


i and oldj should probably be size_t. The same for other ints
throughout.


string[] r;
foreach(j, c; s)


The first j is declared here.


{
static if (is(T == char))
{
if (c == d)
{
if (!ok) { oldj++; continue; }
if (r.length = i) r.length += 5;
r[i] = s[oldj..j];
i++; oldj = j+1;
ok = false;
} else if (!ok) ok = true;
}
else if (is(T == string))
{
/*
for(int j = 0; j  s.length - d.length; j++)


This j would shadow the one above. Just choose another name.


{
if (s[j..j + d.length] == d)
{
if (!ok) { oldj++; continue; }
if (i == r.length) r.length += 5;
r[i] = s[oldj..j - d.length + 1];
i++; oldj = j + d.length;
ok = false;
} else if (!ok) ok = true;

}
*/
}
}
if (oldj  s.length)
{
if (r.length = i) r.length++;
r[i] = s[oldj..$];
i++;
}
r.length = i;
return r;
}


Fastest way to append char to string?

2012-12-11 Thread Chopin

Is this the fastest way to append a char to string?

char c = 'a';
string s;
s ~= c;

?

I have a program that does this many many times... and it's slow. 
So I was wondering it it could be it.


Thanks for tips!


Re: Fastest way to append char to string?

2012-12-11 Thread monarch_dodra

On Tuesday, 11 December 2012 at 15:52:31 UTC, Chopin wrote:

Is this the fastest way to append a char to string?

char c = 'a';
string s;
s ~= c;

?

I have a program that does this many many times... and it's 
slow. So I was wondering it it could be it.


Thanks for tips!


This may or may not be the fastest way.

This should give you a good idea of what's going on:
http://dlang.org/d-array-article.html


Re: Fastest way to append char to string?

2012-12-11 Thread bearophile

Chopin:


Is this the fastest way to append a char to string?

char c = 'a';
string s;
s ~= c;

?

I have a program that does this many many times... and it's 
slow. So I was wondering it it could be it.


Try the appender from std.array. It's supposed to be faster, but 
sometimes it's not faster. There was a patch to make it actually 
faster, but I don't know if it was already merged.


But if your program is slow, then first of all profile it with 
-profile. Then define what you mean by slow.


Bye,
bearophile


Re: char and string with umlauts

2011-10-22 Thread Jim Danley
My thanks to everyone who responded.  I learned something new, which is 
always a good thing, plus my program now works correctly!


Take care,

Jim

- Original Message - 
From: Jonathan M Davis jmdavisp...@gmx.com

To: digitalmars.D.learn digitalmars-d-learn@puremagic.com
Sent: Thursday, October 20, 2011 8:19 PM
Subject: Re: char and string with umlauts



On Thursday, October 20, 2011 09:48 Jim Danley wrote:
I have been a programmer for many years and started using D about one 
year

back. Suddenly, I find myself in unfamiliar territory. I need to used
Finish umlauts in chars and strings, but they are not part of my usual
American ASCII character set.

Can anyone point me in the right direction? I am getting Invalid UTF-8
sequence errors.


I'd have to see code to really say much about what you're doing. But char 
is a
UTF-8 code unit, wchar is a UTF-16 code unit, and dchar is a UTF-32 code 
unit.
For UTF-8 and UTF-16, it can take multiple code units to make a single 
code
point, and a code point is typically what you would consider to be a 
character

(it's actually possible for one code point to alter another - e.g. add an
accent or superscript to it - so a true character would be what is called 
a
grapheme, but for the most part, you don't need to worry about that; at 
the
moment, D doesn't do anything special to support graphemes). So, when 
you're

operating on characters in D, you want to operate on dchars, not chars or
wchars, because they're not necessarily complete characters. That's why 
range-
based functions treat all strings as ranges of dchar, even if they're 
arrays
of char or wchar (e.g. front returns a dchar, not a char or wchar). It's 
also

why when iterating over a string with foreach, you want to specify the
iteration type. e.g.

foreach(dchar c; str)

not

foreach(c; str)

Since iterating over the individual code units really isn't what you want.
Basically, you pretty much never want to operate on an individual char or
wchar. Always make sure that you operate on dchars when operating on
individual characters.

- Jonathan M Davis





char and string with umlauts

2011-10-20 Thread Jim Danley
I have been a programmer for many years and started using D about one year 
back.  Suddenly, I find myself in unfamiliar territory.  I need to used 
Finish umlauts in chars and strings, but they are not part of my usual 
American ASCII character set.


Can anyone point me in the right direction?  I am getting Invalid UTF-8 
sequence errors.


Thanks,

Jim



Re: char and string with umlauts

2011-10-20 Thread Trass3r

Make sure your source file is saved in UTF-8 format.


Re: char and string with umlauts

2011-10-20 Thread Jonathan M Davis
On Thursday, October 20, 2011 09:48 Jim Danley wrote:
 I have been a programmer for many years and started using D about one year
 back. Suddenly, I find myself in unfamiliar territory. I need to used
 Finish umlauts in chars and strings, but they are not part of my usual
 American ASCII character set.
 
 Can anyone point me in the right direction? I am getting Invalid UTF-8
 sequence errors.

I'd have to see code to really say much about what you're doing. But char is a 
UTF-8 code unit, wchar is a UTF-16 code unit, and dchar is a UTF-32 code unit. 
For UTF-8 and UTF-16, it can take multiple code units to make a single code 
point, and a code point is typically what you would consider to be a character 
(it's actually possible for one code point to alter another - e.g. add an 
accent or superscript to it - so a true character would be what is called a 
grapheme, but for the most part, you don't need to worry about that; at the 
moment, D doesn't do anything special to support graphemes). So, when you're 
operating on characters in D, you want to operate on dchars, not chars or 
wchars, because they're not necessarily complete characters. That's why range-
based functions treat all strings as ranges of dchar, even if they're arrays 
of char or wchar (e.g. front returns a dchar, not a char or wchar). It's also 
why when iterating over a string with foreach, you want to specify the 
iteration type. e.g.

foreach(dchar c; str)

not

foreach(c; str)

Since iterating over the individual code units really isn't what you want. 
Basically, you pretty much never want to operate on an individual char or 
wchar. Always make sure that you operate on dchars when operating on 
individual characters.

- Jonathan M Davis


Re: char and string with umlauts

2011-10-20 Thread Ali Çehreli
On Thu, 20 Oct 2011 19:48:54 +0300, Jim Danley wrote:

 I have been a programmer for many years and started using D about one
 year back.  Suddenly, I find myself in unfamiliar territory.  I need to
 used Finish umlauts in chars and strings, but they are not part of my
 usual American ASCII character set.

As Trass3r said, the source code must be saved in a standard Unicode 
encoding. UTF-8 just works.

If your editor is UTF-8, then you should be able to use a Finnish 
keyboard or copy/paste from another source like a web page or a character 
map program in your system. (I use Emacs under Ubuntu with a Turkish 
quail keyboard mapping, which has been designed by me.)

 Can anyone point me in the right direction?  I am getting Invalid UTF-8
 sequence errors.

Could you please show a simple program?

 
 Thanks,
 
 Jim

Ali


Re: char and string with umlauts

2011-10-20 Thread GrahamC

On Thu, 20 Oct 2011 19:48:54 +0300, Jim Danley wrote:

 I have been a programmer for many years and started using D about one
 year back.  Suddenly, I find myself in unfamiliar territory.  I need to
 used Finish umlauts in chars and strings, but they are not part of my
 usual American ASCII character set.

As Trass3r said, the source code must be saved in a standard Unicode 
encoding. UTF-8 just works.

If your editor is UTF-8, then you should be able to use a Finnish 
keyboard or copy/paste from another source like a web page or a character 
map program in your system. (I use Emacs under Ubuntu with a Turkish 
quail keyboard mapping, which has been designed by me.)

 Can anyone point me in the right direction?  I am getting Invalid UTF-8
 sequence errors.

Could you please show a simple program?

 
 Thanks,
 
 Jim

Ali


If your text editor doesn't handle UTF-8 then the \u escape followed by 4 digit 
hex value
can be used, e.g.

dchar[] lit = \u0103\u0102\u00e4\u00c4;
writefln(%s, lit);


Re: char[] to string

2011-06-11 Thread bearophile
Jonathan M Davis:

 Even better though, would be to use std.conv.to - e.g. to!string(input). This 
 will 
 convert input to a string, but it has the advantage that if input is already 
 a 
 string, then it'll just return the string rather than making another copy 
 like 
 idup would.

I didn't know this. Isn't it very good to give this bit of intelligence to idup 
too?

Bye,
bearophile


  1   2   >