www.digitalmars.com         C & C++   DMDScript  

D - Sorting strings!

reply "Andrew Edwards" <crxace13 comcast.net> writes:
I'm trying to sort an array and display the result,
then display a tally of each character in the string.
tried using string.sort property but I'm at a lost.
Also, what is the exact meaning of %s?

Thanks,
Andrew
-----------------------------
int main(char[][] args)
{
   char[] where = "Where in D world is C++?";
   char[] why = " And why are you still using it?";
   char[] question;
   
   question = where~why;
   printf("This is a string, and so is the one below.\n");
   printf(question);
   printf("\n");
   printf("Which has %d characters.\n", question.length);
   return 0;
}
Jun 14 2002
parent reply Burton Radons <loth users.sourceforge.net> writes:
Andrew Edwards wrote:
 I'm trying to sort an array and display the result,
 then display a tally of each character in the string.
 tried using string.sort property but I'm at a lost.
Congratulations, you found a bug. For Walter: char [] array = "foobar"; array.sort; /* Doesn't modify the array */ Also: void b() { int[] a = [1, 2]; } Provokes "Assertion failure: 'ie' on line 253 in file 'declaration.c'". Putting the declaration outside of the function doesn't provoke the error. Finally, int [char] and int [wchar] don't work properly... more details on request. Back to Andrew. If you're also having trouble with the tallying, the ideal way to do this is through associative arrays. We're pooling the chars into little piles - a task well suited for the facility. Pass the string through the function: int [int] tallyho (char [] string) { int [int] array; for (int c = 0; c < string.length; c ++) array [string [c]] ++; return array; } You can then do: int [int] tally = tallyho (string); int [] keys = tally.dup.keys; keys.sort; for (c = 0; c < keys.length; c ++) printf (" ch=%c count=%d\n", keys [c], tally [keys [c]]); The ".dup" in the keys declaration may be unnecessary, but I don't know if modifying the dynamic keys array will cause the universe to implode eventually. But if you don't sort the keys, they'll come out quite random.
 Also, what is the exact meaning of %s?
Do you mean when I referred to it? I was just meaning that if my idea were enacted, you wouldn't generally need any other formatting character - you could have, say: printf ("%s %s %s", "hello", 4, 7.6); There are technical reasons for not doing this so I probably shouldn't have mentioned it.
Jun 14 2002
next sibling parent Burton Radons <loth users.sourceforge.net> writes:
Burton Radons wrote:
 You can then do:
 
     int [int] tally = tallyho (string);
     int [] keys = tally.dup.keys;
I'm sorry, I mean tally.keys.dup here.
Jun 14 2002
prev sibling next sibling parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
	charset="iso-8859-1"
Content-Transfer-Encoding: 7bit

Andrew wrote:

 Also, what is the exact meaning of %s?
"Burton Radons" wote: | Do you mean when I referred to it? I was just meaning that if my idea | were enacted, you wouldn't generally need any other formatting character | - you could have, say: | | printf ("%s %s %s", "hello", 4, 7.6); I wasn't referring to that thread, but rather trying to nail down an exacet meaning for %s as defined in D. I'm under the impression that it means print string but everytime I use it I get unexpected results. Maybe I'm using it incorrectly? See line 26 in attachment. | There are technical reasons for not doing this so I probably shouldn't | have mentioned it. What were those reasons again? I think it's a great Idea!
Jun 14 2002
parent "Pavel Minayev" <evilone omen.ru> writes:
"Andrew Edwards" <crxace13 comcast.net> wrote in message
news:aedfq2$i58$1 digitaldaemon.com...

 I wasn't referring to that thread, but rather trying to nail down an
exacet
 meaning for %s as defined in D. I'm under the impression that it means
 print string but everytime I use it I get unexpected results. Maybe I'm
 using it incorrectly? See line 26 in attachment.
Whenever you want to print a D string (char[]), you need to use %.*s %s means a C-style, null-terminated string.
Jun 14 2002
prev sibling parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
Some additional questions:

Say I establish the string: char[] myString
how do I restrict it's size to exactly what the user inputs?

Additionally, what is the standard input function for D? scanf()?
Jun 14 2002
parent reply "Pavel Minayev" <evilone omen.ru> writes:
"Andrew Edwards" <crxace13 comcast.net> wrote in message
news:aedge3$imo$1 digitaldaemon.com...

 Some additional questions:

 Say I establish the string: char[] myString
 how do I restrict it's size to exactly what the user inputs?
There is no way to do it using the C scanf(), but if you use my stream.d module, you can use stdin.scanf() and the %.*s format specifier. It reads the string of unlimited length, and stores it into a char[], modifying length as needed: import stream; int main() { char[] name; stdout.printf("Enter your name: "); stdin.scanf("%.*s", name); stdout.printf("Hello, %.*s!", name); return 0; }
 Additionally, what is the standard input function for D? scanf()?
There's no standard input (as well as output) in D yet. You can rely on printf() and scanf() being there, sure, but I guess these won't be the ones you use in final version of the language. While printf() covers most needs, scanf() cannot even read D strings, and I had to rewrite it from scratch just to achieve this!
Jun 14 2002
parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
|     import stream;
| 
|     int main()
|     {
|         char[] name;
|         stdout.printf("Enter your name: ");
|         stdin.scanf("%.*s", name);
|         stdout.printf("Hello, %.*s!", name);
|         return 0;
|     }
| 

Thanks Pavel! Sorry for not getting back to this earlier!
Just tried to run this snip and was unsuccessful!
user input is requested but not accepted.

Output looks like this:

Enter your name: Andrew Edwards
Hello, !

?????
Jun 19 2002
parent reply Pavel Minayev <evilone omen.ru> writes:
On Wed=2C 19 Jun 2002 16=3A54=3A04 -0400 =22Andrew Edwards=22
=3Ccrxace13=40comcast=2Enet=3E 
wrote=3A

=3E |     import stream=3B
=3E | 
=3E |     int main=28=29
=3E |     {
=3E |         char=5B=5D name=3B
=3E |         stdout=2Eprintf=28=22Enter your name=3A =22=29=3B
=3E |         stdin=2Escanf=28=22%=2E*s=22=2C name=29=3B
=3E |         stdout=2Eprintf=28=22Hello=2C %=2E*s!=22=2C name=29=3B
=3E |         return 0=3B
=3E |     }
=3E | 
=3E 
=3E Thanks Pavel! Sorry for not getting back to this earlier!
=3E Just tried to run this snip and was unsuccessful!
=3E user input is requested but not accepted=2E

Yep=2C my mistake=2E When you read D strings=2C you must pass
an =5Faddress=5F to a D string=2C and not the string itself=2E So=3A

=09stdin=2Escanf=28=22%=2E*s=22=2C &name=29=3B=09=2F=2F note the &

Now it works!
Jun 20 2002
parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
there's another problem,
running the program with stdin & stdout generate the following errors:

no property 'printf' for type '_iobuf'
no property 'scanf' for type '_iobuf'

so I take them out and I get the following:

Enter your name: Andrew Edwards
Hello, !

I've imported the following library files:

c.stdio
c.stdlib
stream

Program does not work with or without them.

"Pavel Minayev" <evilone omen.ru> wrote in message
news:CFN374275326275694 news.digitalmars.com...
On Wed, 19 Jun 2002 16:54:04 -0400 "Andrew Edwards" <crxace13 comcast.net>
wrote:

 |     import stream;
 |
 |     int main()
 |     {
 |         char[] name;
 |         stdout.printf("Enter your name: ");
 |         stdin.scanf("%.*s", name);
 |         stdout.printf("Hello, %.*s!", name);
 |         return 0;
 |     }
 |

 Thanks Pavel! Sorry for not getting back to this earlier!
 Just tried to run this snip and was unsuccessful!
 user input is requested but not accepted.
Yep, my mistake. When you read D strings, you must pass an _address_ to a D string, and not the string itself. So: stdin.scanf("%.*s", &name); // note the & Now it works!
Jun 20 2002
parent reply Pavel Minayev <evilone omen.ru> writes:
On Thu=2C 20 Jun 2002 07=3A54=3A03 -0400 =22Andrew Edwards=22
=3Ccrxace13=40comcast=2Enet=3E 
wrote=3A

=3E there's another problem=2C
=3E running the program with stdin & stdout generate the following errors=3A
=3E 
=3E no property 'printf' for type '=5Fiobuf'
=3E no property 'scanf' for type '=5Fiobuf'
=3E 
=3E so I take them out and I get the following=3A
=3E 
=3E Enter your name=3A Andrew Edwards
=3E Hello=2C !
=3E 
=3E I've imported the following library files=3A
=3E 
=3E c=2Estdio
=3E c=2Estdlib
=3E stream

The problem is=2C there is a nameclash between C stdin=2Fstdout=2Fstderr=2C
declared
somewhere in c=2Estdio I guess=2C and mine=2E When you took those out=2C you
were
actually calling global scanf=28=29=2C which does not support D strings
=28stream=2Ed
has a rewritten version of it=29=2E So=2C either you provide the fully qualified
name=2C like this=3A

=09stream=2Estdin=2Escanf=28=22=2E*s=22=2C &name=29=3B

Or declare an alias=3A

=09File cin=2C cout=2C cerr=3B
=09static this=28=29
=09{
=09=09cin =3D stream=2Estdin=3B
=09=09cout =3D stream=2Estdout=3B
=09=09cerr =3D stream=2Estderr=3B
=09}

You could also add the above into stream=2Ed itself =28I will probably do it
myself
for the next version=29=2E Or just don't import c=2Estdlib and
c=2Estdio=2E=2E=2E

By the way=2C what should be the new name for standard streams=3F Since std* is
already taken by C ones=2C should I use cin=2Fcout=2Fcerr=3F Or something
else=3F
I will appreciate any ideas=2E=2E=2E
Jun 20 2002
next sibling parent "Sean L. Palmer" <seanpalmer earthlink.net> writes:
Can't use sin/sout because sin is a math function.

Probably fin/fout would be bad because fin can mean "end" in some languages.
;)

Sean

"Pavel Minayev" <evilone omen.ru> wrote in message
news:CFN374277721585648 news.digitalmars.com...
On Thu, 20 Jun 2002 07:54:03 -0400 "Andrew Edwards" <crxace13 comcast.net>
wrote:

 there's another problem,
 running the program with stdin & stdout generate the following errors:

 no property 'printf' for type '_iobuf'
 no property 'scanf' for type '_iobuf'

 so I take them out and I get the following:

 Enter your name: Andrew Edwards
 Hello, !

 I've imported the following library files:

 c.stdio
 c.stdlib
 stream
The problem is, there is a nameclash between C stdin/stdout/stderr, declared somewhere in c.stdio I guess, and mine. When you took those out, you were actually calling global scanf(), which does not support D strings (stream.d has a rewritten version of it). So, either you provide the fully qualified name, like this: stream.stdin.scanf(".*s", &name); Or declare an alias: File cin, cout, cerr; static this() { cin = stream.stdin; cout = stream.stdout; cerr = stream.stderr; } You could also add the above into stream.d itself (I will probably do it myself for the next version). Or just don't import c.stdlib and c.stdio... By the way, what should be the new name for standard streams? Since std* is already taken by C ones, should I use cin/cout/cerr? Or something else? I will appreciate any ideas...
Jun 20 2002
prev sibling next sibling parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
Pavel wrote:

 By the way, what should be the new name for standard streams? Since std*
is
 already taken by C ones, should I use cin/cout/cerr? Or something else?
 I will appreciate any ideas...
how about input/output/error?
Jun 20 2002
parent reply Pavel Minayev <evilone omen.ru> writes:
On Thu, 20 Jun 2002 14:09:14 -0400 "Andrew Edwards" <crxace13 comcast.net> 
wrote:

 Pavel wrote:
 
 By the way, what should be the new name for standard streams? Since std*
is
 already taken by C ones, should I use cin/cout/cerr? Or something else?
 I will appreciate any ideas...
how about input/output/error?
"input" sounds like a name of the action, not an object... besides, there's already class Error, and I'd like to avoid such small differences.
Jun 20 2002
parent "Andrew Edwards" <crxace13 comcast.net> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:CFN374279564276852 news.digitalmars.com...

| "input" sounds like a name of the action, not an object... besides,
there's
| already class Error, and I'd like to avoid such small differences.

good points... My final suggestion would be to use din/dout/derr.
Otherwise id say to go with cin/cout/cerr. Besides, not to many people will
have a problem using cin/cout/cerr because they are already familiar with
it.
Jun 20 2002
prev sibling parent reply "Andrew Edwards" <crxace13 comcast.net> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:CFN374277721585648 news.digitalmars.com...
On Thu, 20 Jun 2002 07:54:03 -0400 "Andrew Edwards" <crxace13 comcast.net>
wrote:

 You could also add the above into stream.d itself (I will probably do it
myself
 for the next version). Or just don't import c.stdlib and c.stdio...
progress made but still experiencing problems. I decided not to import c.stdlib and c.stdio but when I compile the program I get the following error messages: untitled.obj(untitled) Error 42: Symbol Undefined _Dstream_stdout_C4File untitled.obj(untitled) Error 42: Symbol Undefined _Dstream_stdin_C4File --- errorlevel 2 note: prior to compiling I went to your (Pavel) website and downloaded stream.d to replace the one in the src directory. Don't know if that makes a difference.
Jun 20 2002
parent reply Pavel Minayev <evilone omen.ru> writes:
On Thu=2C 20 Jun 2002 15=3A04=3A42 -0400 =22Andrew Edwards=22
=3Ccrxace13=40comcast=2Enet=3E 
wrote=3A

=3E progress made but still experiencing problems=2E
=3E I decided not to import c=2Estdlib and c=2Estdio but when I compile the
program
=3E I get the following error messages=3A
=3E 
=3E untitled=2Eobj=28untitled=29
=3E  Error 42=3A Symbol Undefined =5FDstream=5Fstdout=5FC4File
=3E untitled=2Eobj=28untitled=29
=3E  Error 42=3A Symbol Undefined =5FDstream=5Fstdin=5FC4File
=3E --- errorlevel 2
=3E 
=3E note=3A prior to compiling I went to your =28Pavel=29 website and downloaded
=3E stream=2Ed to replace the one in the src directory=2E Don't know if that
makes
=3E a difference=2E

The problem is simple=3A you still =5Flink=5F with the old version of
stream=2Ed=2C
because it is inside phobos=2Elib=2C which is linked first=2E You need to patch
your phobos=2Elib to replace old stream=2Eobj inside it with the new one=2E Just
copy stream=2Eobj to D's LIB directory=2C then go there and type=3A

=09lib phobos=2Elib -+stream=2Eobj=3B

Whew=2E=2E=2E =3D=29
 
Jun 21 2002
next sibling parent "Andrew Edwards" <crxace13 comcast.net> writes:
"Pavel Minayev" <evilone omen.ru> wrote in message
news:CFN374285988543056 news.digitalmars.com...
On Thu, 20 Jun 2002 15:04:42 -0400 "Andrew Edwards" <crxace13 comcast.net>
wrote:

 lib phobos.lib -+stream.obj;
Thanks! Problem eliminated. ---------------------------------------- Next stage in development: ---------------------------------------- what is the D "stream" equivalent of establishing an output or input stream and binding it to a file? C++ e.g.: ifstream inData; ofstram outData; int main() { ... inData.open ("input.dat"); ... inData.close outData.open ("output.dat") ... outData.close ... return 0; } Thanks Andrew
Jun 23 2002
prev sibling parent "Carlos" <carlos8294 msn.com> writes:
I did what you said (lib phobos.lib -+ stream.obj), but when I try this:

import file;
import stream;
import c.stdio;

void main()
{
    File input=new File(GetStdHandle(-10), FileMode.In);

    char [30] W;

    scanf("%s",(char*)W);
    printf("%s\n",(char*)W);

    char [] w;

    input.scanf("%.*s",w);
    printf("%.*s\n",w);
}

I get this:

windows.d(14067): function GetStdHandle symbol windows.GetStdHandle
conflicts wi
th stream.GetStdHandle at stream.d(1125)

Now what?

-------------

"Pavel Minayev" <evilone omen.ru> escribio en el mensaje
news:CFN374285988543056 news.digitalmars.com...
On Thu, 20 Jun 2002 15:04:42 -0400 "Andrew Edwards" <crxace13 comcast.net>
wrote:


The problem is simple: you still _link_ with the old version of stream.d,
because it is inside phobos.lib, which is linked first. You need to patch
your phobos.lib to replace old stream.obj inside it with the new one. Just
copy stream.obj to D's LIB directory, then go there and type:

lib phobos.lib -+stream.obj;
Jun 24 2002