In Racket, (read) and (write) know all the builtin datatypes
<https://docs.racket-lang.org/reference/reader.html?q=readtable#%28part._parse-number%29>
which
are already structured more than a stream of bytes (like in C).
Thus, you don't need scanf to tell Racket what is the type of the next
token.

That *is* painful in a situation like coding challenges since the input
format is language independent (however actually it's the C style).
Of course this kind of situation also has its own fixed format, you can
define your own read tables
<https://docs.racket-lang.org/reference/readtables.html?q=readtable> :
1. the "," is special in Racket, you need to drop off them first;
(with-input-from-string
"[04 foo 03.5]" read) gives you '(4 foo 3.5) directly.
2. Symbols are internal Strings, you need (symbol->string) to covent them
into normal Strings (Yes, sometimes, I think if there are string-like or
bytes-like APIs that work on symbols directly).


On Wed, Mar 23, 2016 at 4:33 AM, rom cgb <[email protected]> wrote:

> Hi,
>
> I recently started using Racket and i couldn't find a good alternative to
> C's scanf/printf in the racket standard library. When doing programming
> challenges, you often need to comply to a specific input/ouput thus having
> something like scanf for string to values and printf for values to string
> is comfy.
>
> For example, let's say a challenge where you simply have to output the
> input but you need to translate the strings input into values and then
> those values back to strings.
>
> The given input(and excepted ouput) is
>
>   3
>   [04, foo, 03.5]
>   [05, bar, 04.6]
>   [06, fun, 05.7]
>
> In C, you would simply do
>
>   #include <stdio.h>
>
>   int main(void)
>   {
>       int n;
>
>       // Read number of rows
>       scanf("%d\n", &n);
>
>       // Output number of rows
>       printf("%d\n", n);
>
>       // Process rows
>       for (unsigned int i; i < n; ++i)
>       {
>           int a;
>           char b[20];
>           float c;
>
>           // Read row
>           scanf("[%d, %[^,], %f]\n", &a, b, &c);
>
>           // Output row
>           printf("[%02d, %s, %04.1f]\n", a, b, c);
>       }
>   }
>
> Now, for a solution in Racket, You first have to read the first line and
> convert it into a number.
>
>   (define rows (string->number (read-line)))
>
> Then, for all rows, read and split the string. The best that i have found
> to do that is using regular expressions.
>
>   (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]" (read-line)))
>
> Then you have to manually convert the substrings into values
>
>   (define a (string->number (second split-row)))
>   (define b (third split-row))
>   (define c (string->number (fourth split-row)))
>
> Then you have to manually convert the values back into strings
>
>   (printf "[~a, ~a, ~a]\n"
>           (~a a #:width 2 #:align 'right #:pad-string "0")
>           b
>           (~r c #:min-width 4 #:precision 1 #:pad-string "0")))
>
> This is way more tedious than with the classical input/output format,
> especially when you are doing coding challenges.
>
> Final Racket solution:
>
>   #lang racket
>
>   (define rows (string->number (read-line)))
>
>   (for ([in-range rows])
>     (define split-row (regexp-match #rx"\\[(.+), (.+), (.+)\\]"
> (read-line)))
>
>     (define a (string->number (second split-row)))
>     (define b (third split-row))
>     (define c (string->number (fourth split-row)))
>
>     (printf "[~a, ~a, ~a]\n"
>             (~a a #:width 2 #:align 'right #:pad-string "0")
>             b
>             (~r c #:min-width 4 #:precision 1 #:pad-string "0")))
>
>
> Having something like (not necessary the same specifiers as with printf)
>
>   (string-scan "[%d, %s, %f]" "[45, foo, 10.9]") -> '(45 "foo" 10.9)
>
> and a proper output formatter would be comfy.
>
> Are racket devs against such a thing in the standard library ?
> How you guys are actually doing IO in racket ?
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to