Formatowanie tekstu

2010-12-12 19:03

Tematem budowania łańcuchów znaków zajmowałem się już kiedyś, badając efektywność tej operacji w C++ dla trzech różnych sposobów. Tym razem przyjrzę się sprawie z perspektywy bardziej niezależnej od języka. Ostatnio poczyniłem bowiem pewną obserwację. Zauważyłem mianowicie, że “tradycyjne” podejście do składania stringów – przez konkatenację kolejnych podciągów – staje się… hmm… niemodne, jeśli można tu użyć takiego określenia.

Ci, którzy kodują nieco dłużej niż ja pewnie zwrócą mi zaraz uwagę, że takie naprawdę tradycyjne podejście do problemu to to, które implementują funkcje z języka C podobne do printf:

  1. fprintf (stderr, "[%s] Error (errno=%d)\n", tag, errno);

Polega ono na uprzednim zdefiniowaniu wzorca tekstu (tzw. formatu, tutaj jest to drugi argument fprintf), zawierającego symbole zastępcze takie jak %s czy %d. Są one następnie zastępowane podanymi wartościami (tutaj: tag oraz errno) w celu wyprodukowania finalnego ciągu. Nie ma tu jawnej operacji łączenia dwóch napisów. Zamiast tego mały parser przegląda podany wzorzec i w miejscu symboli zastępczych wstawia do wyniku podane wartości, przepisując bez zmian resztę znaków.
Wkrótce jednak nadszedł C++ z klasami string i ostream, oferującymi podobne możliwości bez użycia wzorców. Zamiast tego posługiwały się operatorami + i << w celu wyprodukowania tekstowego wyjścia:
cerr << "[" << tag << "] Error (errno=" << errno << ")" << endl;[/cpp] To działa, ale - jak można zobaczyć w porównaniu - wygląda często znacznie mniej przejrzyście. Nie dziwi więc, że w tym względzie historia zdaje się zatoczyć koło. Obecnie bowiem operacja formatowania napisów (w sensie powyższej funkcji fprintf, a nie określania czcionki czy stylu tekstu) jest wbudowana w wiele nowoczesnych, popularnych języków programowania, jak choćby C#, Pythona czy Javę. Najczęściej też, co ciekawe, trzyma się ona z grubsza oryginalnej składni wzorców pochodzącej jeszcze z C, dodając oczywiście jakieś własne, bardziej zaawansowane rozszerzenia:

  1. exc_type, exc, _ = sys.exc_info()
  2. logging.error("[%s] %s" , exc_type.__name__, exc)
  1. Console.WriteLine("[{0}] {1}", e.GetType().Name, e.Message);

Czasami jednak – jak widać wyżej – tak nie jest :) Na obecność mechanizmu formatowania łańcuchów znaków możemy aczkolwiek liczyć w każdym szanującym się języku. I to łącznie z C++, gdzie wszystko prawie wszystko, czego w nim pierwotnie nie ma, zawiera się w jakiejś bibliotece boost – w tym przypadku jest to boost::format.

Tags: , , , ,
Author: Xion, posted under Programming »


5 comments for post “Formatowanie tekstu”.
  1. MySZ:
    December 12th, 2010 o 21:06

    Python 3.x (później chyba backport do Pythona 2.6) wprowadza metodę format dla obiektu String. Działa to i wygląda podobnie jak to dla C#. Ogólnie bardzo rozbudowane, ze sporymi możliwościami. Najlepiej przeczytać dokumentację: Format String Syntax.

  2. dynax:
    December 12th, 2010 o 22:05

    To formatowanie bardzo często ułatwia życie. Zamiast wielu “<<" piszemy sobie po prostu wzorzec i podstawiamy argumenty :)

  3. Dab:
    December 13th, 2010 o 14:52

    Jest jeszcze “Gracz {PLAYER} zdobyl {ITEM} na mapie {MAP}”. Duzo fajniej sie sprawdza przy np. tlumaczeniach niz kombinowanie z rozszerzeniami printf do zmiany kolejnosci argumentow.

  4. Asmodeusz:
    December 13th, 2010 o 15:43

    @Dab: zmiana kolejności parametrów jest możliwa w kilku różnych API (np. QT -> QString::format przyjmuje argumenty w postaci %1, %2 itd.). Podobnie C#.

    Formatowanie i/lub zastępowanie przez regexp są zdecydowanie lepsze w przypadku tłumaczenia na inne języki – gdzie często kolejność słów/wyrażeń może być inna niż w języku bazowym (zwykle angielskim).

  5. Xion:
    December 13th, 2010 o 22:07

    @Asm: Dodatkowo formaty można sobie trzymać w zasobach, a potem rozwijać je przy odczytywaniu.
    Jakie języki wspierają takie formatowanie po kluczach, btw? Na pewno Python i wydaje mi się, że C# też. Nie wiem, jak inne.

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.