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 <romainbeck...@gmail.com> 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 racket-users+unsubscr...@googlegroups.com.
> 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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to