Pe Maria a șocat-o vestea că documentația pentru programele scrise în facultate se face în plain text, pentru că e obișnuită să lucreze în Microsoft Word și să formateze textul cât mai frumos. Ea vrea să găsească cât mai multe moduri prin care să înfrumusețeze un fișier simplu .txt
, așa că folosește ASCII Art și vrea să creeze un program care să formateze textul pentru ea.
Maria vrea ca programul ei să primească trei argumente în linia de comandă. Primul argument reprezintă un șir de caractere care indică operațiile pe care dorește să le aplice textului dintr-un fișier (separate prin virgulă), al doilea argument este calea către fișierul respectiv, iar al treilea argument este numele fișierului formatat care va fi generat.
Puteți porni de la scheletul de cod de aici, care face citirea și scrierea în/din fișier pentru voi. Fișierul Makefile inclus conține regulile build
, clean
și run
. Pentru a da argumente regulii run
, formatul este conform exemplului următor:
make run ARGS='"W 50, C 0 0, L1" in.txt out.txt'
./format_text "W 50, C 0 0, L 1" in.txt out.txt
În exemplul de mai sus se efectuează următoarele operații:
in.txt
W
rap)C
enter)L
eft)out.txt
Maria știe că fișierele pe care le va formata nu vor avea niciodată mai mult de 1.000 de linii sau mai mult de 1.000 de caractere pe o singură linie.
În șirul de caractere care indică operațiile (îl vom numi “comandă”), pot exista oricâte spații între operații și parametri. Acestea nu influențează operațiile. În plus, primul caracter din operație (care diferă în funcție de tipul operației) poate fi atât lowercase, cât și uppercase, având aceeași semnificație. O comandă nu ar trebui să aibă mai mult de 10 operații, iar o operație validă nu are mai mult de 20 de caractere (cu tot cu spații).
Operațiile care au ca parametri [start_line [end_line]]
se aplică pe liniile din intervalul [start_line
, end_line
], sau de la start_line
până la sfârșitul fișierului dacă end_line
nu este precizat. Dacă nici unul dintre cei doi parametri nu este precizat, operația se va efectua pe întregul fișier.
W max_line_length
Operația wrap adaugă și elimină caractere newline din text astfel încât textul să se încadreze în max_line_length
(să aibă lungimea - în octeți - mai mică sau egală), fără a permite linii prea scurte (în afara ultimei linii dintr-un paragraf) și fără a trunchia cuvintele. O linie este prea scurtă dacă primul cuvânt din linia următoare ar fi încăput în ea fără să depășească max_line_length
.
Atunci când două linii l1
și l2
sunt concatenate în urma unei operații wrap, rezultatul obținut va fi “l1` l2`”
unde l1`
este l1
fără trailing whitespace, iar l2`
este l2
fără starting whitespace.
W 60
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida. Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida. Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
Fișierul obținut în ambele cazuri va fi:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida. Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
C [start_line [end_line]]
Operația center folosește ca referință cea mai lungă linie din fișier (fără trailing whitespace) și adaugă spații la începutul liniilor care sunt mai scurte pentru a le centra.
C
:
Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
Fișierul obținut va fi:
Lorem ipsum Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
L [start_line [end_line]]
Operația align left aliniază liniile precizate la marginea din stânga.
L
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
Fișierul obținut va fi:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
R [start_line [end_line]]
Operația align right folosește ca referință cea mai lungă linie din fișier (fără trailing whitespace) și adaugă spații la începutul liniilor care sunt mai scurte pentru a le alinia la marginea din dreapta.
R
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
Fișierul obținut va fi:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida.
J [start_line [end_line]]
Operația justify folosește ca referință cea mai lungă linie din fișier și distribuie în mod echilibrat spații în interiorul liniilor mai scurte pentru ca acestea să ajungă la aceeași lungime și să fie aliniate atât la dreapta, cât și la stânga.
J
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida. Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
Un posibil fișier obținut va fi:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi. Morbi mauris massa, aliquam sed eros in, fringilla accumsan neque. Quisque blandit lobortis purus vitae gravida. Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
Exemplu de rezolvare incorectă (ultimul paragraf din textul de mai sus):
Morbi sit amet euismod leo. Quisque in hendrerit turpis, ac fringilla ante. Sed id mi bibendum, scelerisque arcu vel, rutrum nibh.
P indent_length [start_line [end_line]]
Această operație realizează indentarea automată a paragrafelor din intervalul precizat (dacă există), cu indent_length
spații (maxim 8). Se va indenta doar prima linie din fiecare paragraf.
P 4
:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi.
Fișierul obținut va fi:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer elementum, ipsum sit amet vulputate semper, orci justo condimentum felis, eu lobortis metus quam ac mauris. Mauris sed pharetra leo. Morbi mollis nunc eu velit tincidunt ullamcorper. Vestibulum finibus tellus ac lobortis porttitor. Integer a lacus nisi.
I list_type special_character [start_line [end_line]]
Această operație formatează liniile corespunzătoare ca pe o listă (aliniată la stânga) a cărei indici sunt definiți în funcție de parametrii list_type
și special_character
.
Parametrul list_type
indică tipul listei:
n
→ listă numerotatăa|A
→ listă alfabetică (cu litere mici sau mari)b
→ bullet list
În funcție de tipul listei, parametrul special_character
indică:
Caracterele speciale folosite vor fi întotdeauna urmate de spațiu.
apples oranges cherries
Observați câteva exemple de operații și fișierele rezultate:
I n .
1. apples 2. oranges 3. cherries
I a )
a) apples b) oranges c) cherries
I A .
A. apples B. oranges C. cherries
I b -
- apples - oranges - cherries
I b *
* apples * oranges * cherries
sprintf
pentru formatare.
Se știe că nu vor exista niciodată mai mult de 26 de elemente în listă, așadar în cazul indicilor alfabetici, nu se va depăși niciodată indicele 'Z'.
O list_type special_character ordering [start_line [end_line]]
Această operație funcționează exact la fel ca operația precedentă I
(formatează liniile corespunzătoare ca pe o listă a cărei indici sunt definiți în funcție de parametrii list_type
și special_character
), dar în plus face și ordonarea alfabetică a elementelor din listă.
Parametrul ordering
indică dacă ordonarea se face alfabetic sau invers alfabetic, putând lua valorile:
a
→ sortare alfabetică normală (de la A la Z)z
→ sortare alfabetică inversă (de la Z la A)
start_line
este mai mare decât numărul de linii din fișier (atenție, nu neapărat din fișierul original! numărul de linii se poate modifica pe măsură ce se aplică operațiile) , operația este ignorată.end_line
este mai mare decât numărul de linii din fișier, dar parametrul start_line
este valid, se va efectua operația de la start_line
până la sfârșitul fișierului (ca și cum end_line
nu ar fi fost precizat).max_line_length
de la operația wrap este mai mică decât lungimea celui mai lung cuvânt din fișierul inițial, se va afișa la stdout
mesajul “Cannot wrap!”, iar fișierul obținut va fi identic cu fișierul inițial.stdout
mesajul “Too many operations! Only the first 10 will be applied.”, iar fișierul obținut va avea aplicate doar primele 10 operații din comandă.stdout
mesajul “Invalid operation!”, iar fișierul obținut va fi identic cu fișierul inițial, dacă:list_type
cu o altă valoare decât cele precizate);W
, C
, L
, R
, J
, P
, I
, O
și au maximum 20 de caractere);start_line
este mai mare ca parametrul end_line
.
max_line_length
, start_line
, end_line
, indent_length
list_type
, special_character
, ordering
TOTAL: 180p
Tema va fi trimisă folosind vmchecker, cursul Programarea Calculatoarelor (CB & CD).
Găsiți checker-ul aici.
stdout
. Nu trebuie să afișați nimic la stdout
, în afară de cele 3 mesaje de eroare precizate în secțiunea Tratarea cazurilor speciale.
Formatul arhivei va fi următorul:
.c
(și fișiere .h
- dacă este cazul).
””
), fișierul obținut va avea același conținut ca cel inițial, dar nu va conține trailing whitespace.