Thread overview
Reading whitespace separated strings from stdin?
Apr 21, 2015
TheGag96
Apr 21, 2015
Adam D. Ruppe
Apr 21, 2015
TheGag96
Apr 21, 2015
Adam D. Ruppe
Apr 21, 2015
weaselcat
Apr 22, 2015
TheGag96
April 21, 2015
Hi guys! I had this homework assignment for data structures that has a pretty easy solution in C++. Reading input like this...

1 2 3 # $
4 3 * ! #
20 3 / # $ #
62 # $
2 3 8 * + #
4 48 4 2 + / #
SUM # $
1 2 3 4 5 #
R #
@

...where "@" denotes the end of input is fairly simple in C++:

string token = "";
while (token != "@") {
  //handle input
}

Note that having newlines doesn't matter at all; every token is just assumed to be separated by "whitespace". However in D, I looked around could not find a solution better than this:

foreach (line; stdin.byLine) {
  foreach (token; line.split) {
    //handle input
  }
}

Is there any way to do this without two loops/creating an array? "readf(" %d", &token);" wasn't cutting it either.

Thanks.
April 21, 2015
I think this should work:

import std.stdio;

void main() {
        string token;
        while(readf("%s ", &token))
                writeln(token);
}


Have you tried that? What is wrong with it if you have?
April 21, 2015
On Tuesday, 21 April 2015 at 01:46:53 UTC, Adam D. Ruppe wrote:
> I think this should work:
>
> import std.stdio;
>
> void main() {
>         string token;
>         while(readf("%s ", &token))
>                 writeln(token);
> }
>
>
> Have you tried that? What is wrong with it if you have?

It'll just leave some trailing whitespace, which I don't want. And somehow doing token = token.stip STILL leaves that whitespace somehow...
April 21, 2015
On Tuesday, 21 April 2015 at 02:04:24 UTC, TheGag96 wrote:
> It'll just leave some trailing whitespace, which I don't want.

oh it also keeps the newlines attached. Blargh.

Well, forget the D functions, just use the C functions:

import core.stdc.stdio;

void main() {
        char[16] token;
        while(scanf("%15s", &token) != EOF)
                printf("**%s**\n", token.ptr);
}



You could convert to a string if needed with import std.conv; to!string(token.ptr), but if you can avoid that, you should, this loop has no allocations which is a nice thing.
April 21, 2015
On Tuesday, 21 April 2015 at 01:31:58 UTC, TheGag96 wrote:
> Hi guys! I had this homework assignment for data structures that has a pretty easy solution in C++. Reading input like this...
>
> 1 2 3 # $
> 4 3 * ! #
> 20 3 / # $ #
> 62 # $
> 2 3 8 * + #
> 4 48 4 2 + / #
> SUM # $
> 1 2 3 4 5 #
> R #
> @
>
> ...where "@" denotes the end of input is fairly simple in C++:
>
> string token = "";
> while (token != "@") {
>   //handle input
> }
>
> Note that having newlines doesn't matter at all; every token is just assumed to be separated by "whitespace". However in D, I looked around could not find a solution better than this:
>
> foreach (line; stdin.byLine) {
>   foreach (token; line.split) {
>     //handle input
>   }
> }
>
> Is there any way to do this without two loops/creating an array? "readf(" %d", &token);" wasn't cutting it either.
>
> Thanks.

import std.stdio;
import std.array;
void main(){
    auto tokens = stdin.readln('@').split;
    writeln(tokens);
}

["1", "2", "3", "#", "$", "4", "3", "*", "!", "#", "20", "3", "/", "#", "$", "#", "62", "#", "$", "2", "3", "8", "*", "+", "#", "4", "48", "4", "2", "+", "/", "#", "SUM", "#", "$", "1", "2", "3", "4", "5", "#", "R", "#", "@"]
April 22, 2015
On Tuesday, 21 April 2015 at 03:44:16 UTC, weaselcat wrote:
> snip

Wow, that's a damn good solution... I didn't know that readln() could take an argument that it stops at once it finds.

Now the thing is, this program is supposed to be a reverse Polish notation calculator. A human using this program would probably be confused as to why nothing happens when they hit enter after a line -- it only really works in the context of copying and pasting the whole input in. Still a really neat solution to know anyhow. Thanks!