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.

