Spezzo in due anche questo.
smalldragon ha scritto:
allora per quanto riguarda la cin sinceramente la potevano fare molto meglio.
mettendo automaticamente nella funzione sia l'autoconversione che il reset del buffer nonche il controllo di validità dei dati.
La conversione c'è (altrimenti non potresti avere i bytes grezzi convertiti in int ad esempio), il controllo c'è (se inserisci un double al posto di un int, lo stream si invalida). Manca il reset del buffer ma a quello si può pensare esternamente.
funzioni del genere esistono in tantissimi linguaggi mi sembra starno che non ci abbiano pensato!
comunque bastava mettere all'inizio della funzione il reset del buffer magari legandolo alla variabile avrebbero scritto qualche riga di codice in più ma avrebbero avuto una funzione migliore.
ed avrebbero risparmiato un bel pò di casini.
Probabilmente ci hanno pensato e hanno deciso che il controllo era oneroso per le prestazioni. Se ti aspetti un int e inserisci un int, il controllo è superfluo e danneggia le prestazioni; se ti aspetti un int e inserisci un double, la colpa non è di cin ma di chi inserisce il dato.
Comunque hai ragione su questo punto, ma se consideri cin una primitiva del linguaggio, nessuno ti impedisce di creare una funzione auto correttiva usando altri costrutti base.
Ma anche così risolvi solo una parte del problema: se ti aspetti in input un int e io continuo a inserire double, l'unica cosa che ottieni e non invalidare l'input ma il dato resta sbagliato.
come vedi da questo spezzone non è poi cosi difficile fare una cin in assembler ma avendo inibito gli interrupt, a livello di programmazione, non la si può più fare così!
Lo spezzone è interessante, ma forse ti è sfuggito il senso del discorso: in base a che criterio decidi che quello che ottieni in input debba essere un float e non una stringa?
Se io inserisco 1.23 hai informazioni sufficienti per sapere se il dato dev'essere acquisito come stringa o come float? Risposta no. Perché se tu mi dici che è un float io ti rispondo che dev'essere acquisito come "1.23"; se mi dici ok, lo acquisisco come "1.23", io ti rispondo che lo voglio float 1.23
Semplicemente non hai informazioni su come trattare il dato fino a che non espliciti in cosa lo vuoi convertire. Ed è questa operazione che si rivela fallace a prescindere dal modo di ottenere l'input da tastiera.
overload delle funzioni questa me la devo studiare sapevo del overload degli operatori (un gran casino!) (grazie per l'informazione)
E' solo perché non ci hai preso la mano. Ma se ci pensi un attimo è più semplice esplicitare una somma tra entità con l'operatore + piuttosto che scrive mille mila funzioni sum_qualcosa che da un punto di vista concettuale non significa molto.
neanche il c scherza prendi per esempio la printf o la scanf e una bella lotta con cin e cout per chi ha la sintassi più astrusa!
Astrusa forse, ma inevitabile. Del resto il problema è sempre quello: come indicare alla funzione in esame di trattare i dati in un certo modo invece che in un altro. Del resto printf e scanf accettano una stringa di formattazione e un numero pressoché infinito di parametri, perciò in qualche modo bisogna dire sia quanti sono sia di che tipo sono.
per quanto riguarda i controlli da una parte hai raggione se si conoscono le dimensioni ok. ma quando le funzioni sono esterne può capitare che le dimensioni non si conoscono così converrebbe che si controllassero per evitare gli sfondamenti.
Ovvio. Quello che sto dicendo è che tali controlli non sempre possono essere fatti all'interno della funzione. Prendiamo di nuovo la tua funzione : InsRightParola (solo la parte iniziale).
int InsRightParola(char *cptr,char *dptr,)
{
int indy,errore,k;
indy = 0; k = 0;
int maxa,maxb,maxstr;
maxa=LenStringa(cptr);
maxb=LenStringa(cptr)
Già qui fai alcuni errori di concetto.
Ricevi dei char* e la funzione non ha informazioni per sapere cosa siano questi char*: possono essere dei buffer, delle stringhe ASCIIZ, un puntatore a un singolo carattere, un puntatore a un buffer dinamico o un altro puntatore a char.
In altre parole tutte queste chiamate sono valide.
char a; char b;
char c[16]; char d[16];
char *x= NULL, *y=NULL;
char* pc = new char[16];
InsRightParola(&a,&b);
InsRightParola(c,d);
InsRightParola(x,y);
InsRightParola(pc,&b);
Al suo interno InsRightParola può solo dire: se quel che ricevo non è NULL facciamo qualcosa.
Ma questo fare qualcosa è subordinato al fatto che chi chiama la funzione abbia informazioni su che cosa tratta la funzione. Ad esempio: InsRightParola unisce la parola destra puntata da dptr con quella a sinistra puntata da cptr se, e solo se, sia cptr e dptr rappresentano delle ASCIIZ string. Se cptr o dptr sono NULL non viene effettuata nessuna operazione. Se cptr o dptr non sono ASCIIZ string (puntatori a un singolo carattere) la funzione ha comportamento indefinito.
Se cptr e dptr sono due ASCIIZ, cptr deve poter contenere la stringa unita altrimenti il comportamento è indefinito.
questo tipo di errori può capitare quando un vettore si riempie facendo dei calcoli e passare ogni volta le dimensioni sarebbe una cosa assurda non trovi?
Per niente: anzi è l'unico modo per evitare sfondamenti indesiderati. Funzioni come la strcpy o la gets sono di fatto deprecate proprio perché non hanno in input l'intervallo di validità su cui operare. Di fatto quello che chiedi è provvisto di serie sotto forma di std::string.
std::string a = "Questa è ";
std::string b = "una stringa unita";
a+=b;
std::cout << a << std::endl;