Autore Topic: dead  (Letto 5051 volte)

Offline legacy

  • ASM Lover
  • *****
  • Post: 353
  • Karma: +14/-2
    • Mostra profilo
dead
« il: 28 Agosto 2015, 16:00:21 »
dead
« Ultima modifica: 17 Gennaio 2020, 12:32:11 da legacy »

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
io dico: un funzione per ogni tipo

plauso di alcuni, sdegno di altri, quindi …. l'informatica e' un sotto insieme della matematica
la matematica non e' una opinione, ma il suo sotto insieme si  :o :o :o :o


boh, cmq mi sembrava una soluzione pulita, quantomeno comoda, ed in ADA fanno proprio cosi'

printf è una piaga (anche il C è una piaga;D
Quelle poche volte che mi ci sono imbattuto in alcuni sorgenti che tentavo di decifrare partivano brutte parole e cattivi pensieri  ::)

Innanzitutto printf() ha senso?  ::)

Esempio:
Citazione
printf("Oggi sono andato al bar %d volte per bere un %s ma non ho pagato perchè mi hanno chiesto %3.2f", 3, 'caffè', 20.5)
Se qua ci mettiamo altri 3 o 4 segnaposto non ci si capisce più una mazza...

Io sono per le cose semplici e sopratutto leggibili, non mi sbilancio con il C perchè sono una capra quindi uso uno pseudocodice dove & è un operatore di concatenazione, Int() conversione a intero, Str() conversione a stringa e PadNum() formatta un numero a n decimali:

Codice: [Seleziona]
printf("Oggi sono andato al bar " & PadNum(a, 0) & " volte per bere un " & Str(b) & " ma non ho pagato perchè mi hanno chiesto " & PadNum(c, 2) & " Euro.", { a=3, b='caffè', c=20.5 })
Questa forma mi permette anche di usare cose molto più leggibili tipo:

Codice: [Seleziona]
printf("Oggi sono andato al bar " & PadNum(a, 0) & " volte per bere un " & Str(bevanda) & " ma non ho pagato perchè mi hanno chiesto " & PadNum(conto, 2) & " Euro.", { volte=3, bevanda='caffè', conto=20.5 })
A questo punto mi permetto di usare questa forma  :P
Citazione
printf("Oggi sono andato al bar %volte volte per bere un %bevanda ma non ho pagato perchè mi hanno chiesto %conto Euro.",
   { volte = PadNum(2, 0),
     bevanda = "caffè",
     conto = PadNum(20.5, 2) })

Altro che &03.4f%d89826$&££/&/(&)("=))£/&$&  :o :o :o :o :o :o :o :o :o :o :o :o

In LUA una roba del genere si implementa in 30 secondi netti.

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Io sono per l'approccio moderno delle Non Mutable Strings, in cui si procede pressappoco come ha descritto Allanon, anche se in realtà la conversione a stringa è quasi sempre implicita.

In Java farei così:

Persona p = new Persona("Pino");
int numero = 7;
String a = "Ciao " + p + ", come stanno i tuoi " + numero + " nani?";

dove la classe Persona eredita forzatamente il metodo toString() dalla classe padre Object. E' poco elegante, poco ortogonale, ma efficace, non prolisso e non ti sminchia lo stack.

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
In C++, volendo, puoi usare std::string che è immutabile e supporta la concatenazione "furba" con l'operatore +.
Ovviamente non è altrettanto type-safe quanto il Java, e devi avere qualche accortezza in più nel definire gli operatori di conversione verso std::string, ma fa il suo porco lavoro meglio del C sicuramente.

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
because they can  ;D


Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
http://stackoverflow.com/questions/10219225/c-create-string-of-text-and-variables

La risposta votata è ottima.
Usa lo String Stream, con l'operatore <<

Rispetto all'uso dell'operatore + sulla stringa stessa, hai il vantaggio di poter usare questa tecnica insieme a buffering, streaming, networking, filesystem, ecc... Se vuoi rendere una tua classe compatibile con questo metodo, devi implementare l'operatore << verso un ostringstream et voilà.

Usato in questo modo è perfettamente type safe e anche molto comodo da scrivere.
« Ultima modifica: 01 ſettembre 2015, 18:32:27 da TheKaneB »

Offline TheKaneB

  • Human Debugger
  • *****
  • Post: 5292
  • Karma: +20/-23
    • Mostra profilo
    • http://www.antoniobarba.org
Considera pure che non scrivo c++ "serio" dal 2010, negli scorsi anni ho usato più Java, PHP e Javascript, per cui sono un po' arrugginito.
Un po' di c++ l'ho usato per un'app Android Qt ma ero quello più skillato del gruppo quindi sono comunque fermo alle mie conoscenze di 5 anni fa.

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
ohhh thanks, io non sono in grado di valutare in toto la bonta' di una soluzione C++
per questo ti chiedevo anche della soluzione GIT qui sopra, che a me .. sembra na roba pessima
molto meglio la soluzione del link che hai postato tu

tinyformat è una libreria che ha il preciso scopo di avere delle funzioni di formattazioni simili alla vecchia (s)printf che però sia type-safe e non abbia tutti i vari problemi della printf del C. Per fare questo, invece di andare a ravanare sullo stack come fa la versione C, usano una tecnica che si chiama variadic template, che permette di costruire funzioni che possono accettare un numero qualsiasi di parametri (come la vecchia printf), però allo stesso tempo mantenendo tutte le informazioni sul tipo di dato per ogni parametro.

(Ovviamente con la stessa tecnica puoi anche costruire funzioni di formattazione più avanzate e meno criptiche della printf, ad esempio guarda C++ Format)

Ciò non è oggettivamente migliore o peggiore rispetto a usare ostringstream, solamente diverso.
Un "problema" che ha l'usare gli stream standard è che il formato della stringa non può essere cambiato facilmente a runtime, perchè l'ordine dei valori e la loro formattazione è stabilita in codice; con le funzioni di formattazione simil-printf, puoi farti dare la stringa di formato dall'esterno in modo che l'output possa essere personalizzato dopo la compilazione.
Ciò è un enorme problema di sicurezza usando la printf in C, perchè in C non c'è nessun controllo che la stringa di formato sia "onesta" e non faccia cose strane; nelle versioni C++ (anche quelle più semplici come tinyformat) hai già di base molta più sicurezza poichè l'implementazione non ha bisogno di andare a puntare nello stack "al buio" sperando che ci siano i dati al posto giusto, ma può verificare che il parametro nella stringa di formato e l'effettiva variabile abbiano lo stesso tipo di dato (oppure può fare una conversione).

Se noti, in C++ Format la stringa di formato non ha più bisogno di indicare il tipo di dato da stampare (anche se lo supporta per combatibilità con printf), perchè quell'informazione la ha già dal compilatore, e non c'è pericolo di sbagliare.

Tags: