I'm a newbie using the Racket language, but I got really stuck with the following problem working with text files. Here's an example of what I am trying to do:
I have a file (test.txt) that contains the following:
((A 10 "Ciel" 10)
(B 15 "Sprite" 10)
(C 20 "Coca-Cola" 10)
(D 12 "Fuze Tea" 10)
(E 50 "Hattori Sake" 10)
(F 40 "02Linn Soju" 10)
(G 16 "Fanta" 10)
(H 25 "Canada Dry" 10)
(A12 54 "Cigars" 10)
(Kiero 78 "Calculator" 10))
And what I want is to overwrite the contents of a line; let's say that at line three I want to replace with: (W 10 "Liquor" 10). This is what I'm expecting:
((A 10 "Ciel" 10)
(B 15 "Sprite" 10)
(W 10 "Liquor" 10)
(D 12 "Fuze Tea" 10)
(E 50 "Hattori Sake" 10)
(F 40 "02Linn Soju" 10)
(G 16 "Fanta" 10)
(H 25 "Canada Dry" 10)
(A12 54 "Cigars" 10)
(Kiero 78 "Calculator" 10))
Before asking this question I was researching on other StackOverflow posts, and I came across a similar situation to mine here. However, it's not the way I want to solve my problem because of these points:
- The solution in that post is with two files. I'm expected to only overwrite/update/modify the same file (test.txt)
- The proposal there is using for-loops; since this is for a series of exercises that are expected to encourage recursion and functional programming I'm not allowed to use them, nor set! set-car!, or anything that resembles the imperative paradigm.
- Lastly, their solution only inserts a text between lines, but it does not overwrite one as such.
I don't want to seem like I'm just coming here to copy-paste a solution from comments, so I did put some effort to code a function. It kinda works, but not in the way I expected. Here's my attempt:
(define (write-line-to-file str line-number filename)
(with-output-to-file filename #:exists 'update
(lambda () (when (>= line-number 1) (newline))
(printf str)(newline))))
Here's my function calling:
(write-line-to-file "(W 10 \"Liquor\" 10)" 2 "test.txt")
And here's what I got:
(W 10 "Liquor" 10)
15 "Sprite" 10)
(C 20 "Coca-Cola" 10)
(D 12 "Fuze Tea" 10)
(E 50 "Hattori Sake" 10)
(F 40 "02Linn Soju" 10)
(G 16 "Fanta" 10)
(H 25 "Canada Dry" 10)
(A12 54 "Cigarros" 10)
(Kiero 78 "Calculadora" 10))
Any idea how to modify the function to do the following:
((A 10 "Ciel" 10)
(B 15 "Sprite" 10)
(W 10 "Liquor" 10)
(D 12 "Fuze Tea" 10)
(E 50 "Hattori Sake" 10)
(F 40 "02Linn Soju" 10)
(G 16 "Fanta" 10)
(H 25 "Canada Dry" 10)
(A12 54 "Cigars" 10)
(Kiero 78 "Calculator" 10))
Instead of this:
(W 10 "Liquor" 10)
15 "Sprite" 10)
(C 20 "Coca-Cola" 10)
(D 12 "Fuze Tea" 10)
(E 50 "Hattori Sake" 10)
(F 40 "02Linn Soju" 10)
(G 16 "Fanta" 10)
(H 25 "Canada Dry" 10)
(A12 54 "Cigars" 10)
(Kiero 78 "Calculator" 10))