PDA

View Full Version : [C]Problema di conversione da stringa a double


pspmaniaco
24-03-2010, 16:52
Buongiorno a tutti,in questo periodo mi sono dedicato all'apprendimento del C e vorrei riuscire a fare un programma completo che racchiuda tutto cio che bene o male ho letto.
Ho quindi deciso di impormi come obbiettivo la realizzazione di una calcolatrice scientifica e di costruirla e aggiungergli funzioni passo passo.
Ora come ora sono passato dai semplici calcoli con 2 operandi a calcoli con un numero variabile di essi;ma nella funzione(di estrapolazione degli operandi degli operatori) che ho fatto non ho una regolare trasformazione tra caratteri e valore double,visto che,nonostante abbia messo dei controlli prende anche i caratteri(come + che vale 48)e li aggiunge ai valori numerici.
Io lavoro col dev C++ su windows e qui (http://rapidshare.com/files/367614066/prova.c.html) c'è il mio file sorgente.

ringrazio in anticipo per i chiarimenti

m0rix93
25-03-2010, 06:51
non ho capito...xD

pspmaniaco
25-03-2010, 14:11
allora mi spiego,il puntatore alla stringa che usavo nel ciclo non puntava a un solo valore della stringa ma puntava stranamente alla somma di 2 valori della stringa stessa,cioè:
stringa[0]=9;
stringa[1]=8;
p=stringa;
dopo questo
*p sarebbe dovuto essere uguale a 9 invece io avevo *p era uguale a 17 perchè mi contava i valori a 2 a 2 e non sapevo perchè.
insomma era *p=stringa[0]+stringa[1].

Alla fine ho risolto ricopiando in un altro sorgente e ricompilando,era un errore del dev c++.

fero86
25-03-2010, 15:02
Buongiorno a tutti,in questo periodo mi sono dedicato all'apprendimento del C e vorrei riuscire a fare un programma completo che racchiuda tutto cio che bene o male ho letto.
Ho quindi deciso di impormi come obbiettivo la realizzazione di una calcolatrice scientifica e di costruirla e aggiungergli funzioni passo passo. dedicati all'apprendimento del C++ anziché del C, cosi poi diventa tutto piu semplice. ecco una semplicissima calcolatrice CUI non scientifica fatta in C++:
#include <iostream>
using namespace std;

int main() {
cin.exceptions(ios::failbit | ios::badbit);
try {
while (true) {
double fFirstOperand, fSecondOperand;
char chOperator;
cin >> fFirstOperand >> ws >> chOperator >> fSecondOperand;
switch (chOperator) {
case '+':
cout << " = " << (fFirstOperand + fSecondOperand) << endl;
break;
case '-':
cout << " = " << (fFirstOperand - fSecondOperand) << endl;
break;
case '*':
cout << " = " << (fFirstOperand * fSecondOperand) << endl;
break;
case '/':
cout << " = " << (fFirstOperand / fSecondOperand) << endl;
break;
default:
cout << "operatore non valido" << endl;
break;
}
}
} catch (ios::failure&) {
cerr << "input non valido" << endl;
}
return 0;
}

pspmaniaco
25-03-2010, 15:09
dici che mi conviene studiare il c++ umh...ci posso provare se non sbaglio vi è un tutorial su wikivideo,casomai puoi consigliarmi un testo completo(in italiano)?
dopo aver studiato il c++(domanda niubba)posso creare un progetto usando entrambi i linguaggi?

P.S:
dedicati all'apprendimento del C++ anziché del C, cosi poi diventa tutto piu semplice. ecco una semplicissima calcolatrice CUI non scientifica fatta in C++:
#include <iostream>
using namespace std;

int main() {
cin.exceptions(ios::failbit | ios::badbit);
try {
while (true) {
double fFirstOperand, fSecondOperand;
char chOperator;
cin >> fFirstOperand >> ws >> chOperator >> fSecondOperand;
switch (chOperator) {
case '+':
cout << " = " << (fFirstOperand + fSecondOperand) << endl;
break;
case '-':
cout << " = " << (fFirstOperand - fSecondOperand) << endl;
break;
case '*':
cout << " = " << (fFirstOperand * fSecondOperand) << endl;
break;
case '/':
cout << " = " << (fFirstOperand / fSecondOperand) << endl;
break;
default:
cout << "operatore non valido" << endl;
break;
}
}
} catch (ios::failure&) {
cerr << "input non valido" << endl;
}
return 0;
}



questa calcolatrice anche in C è banalissima perchè riceve in imput solo 2 operandi,l'ho gia realizzata con successo implementando oltre alle semplici 4 operazioni anche potenza,radice,seno e altre funzioni matematiche,ora come ora stavo ricominciando da capo proponendomi obbiettivi più ampi,per iniziare:ricevere in imput un numero di operandi variabile,poi riconoscere le priorità delle parentesi e cosi via.

fero86
25-03-2010, 15:21
ah be', se puoi scegliere il linguaggio da studiare a quel punto ti direi direttamente C# :D

se ti ho detto C++ é perché tutte le volte che vedo un programma in C penso "ma perché la gente sviluppa ancora in C? ma non vedono quanto viene piu semplice in C++?"

peró se hai totale libertá di scelta il C# costituisce un compromesso di semplicitá, potenza e applicabilitá ineccepibile, e tra l'altro ha un'evoluzione molto piu rapida del C++.

qui c'é la guida in italiano del linguaggio:
http://msdn.microsoft.com/it-it/library/67ef8sbd.aspx
ma ti consiglio di abituarti all'inglese.
qui invece puoi scaricare Visual C# 2008 Express (gratis e legale):
http://www.microsoft.com/express/Downloads/#2008-Visual-CS

pspmaniaco
25-03-2010, 15:41
grz dell'aiuto,in verità io ero propenso allo studio del C perchè con opportune modifiche era possibile applicarlo anche alla psp(mi sarebbe piaciuto lavorarci un o su),quindi il C lo continuerò a usare ma seguirò il tuo consiglio e studierò il C#(e anche il c++ se ho tempo).
P.S:mi resta cmq una domanda è possibile lavorare con più linguaggi in un solo progetto?

fero86
25-03-2010, 16:37
ok, effettivamente con operandi multipli e con le parentesi viene un tantino piu complessa :asd:
#include <iostream>
#include <string>
using namespace std;


class skip {
private:
const string m_str;

public:
skip(string a_str)
:
m_str(a_str) {
}

skip(char ch)
:
m_str(1, ch) {
}

istream &operator () (istream &ris) {
for (string::const_iterator i = m_str.begin(); i != m_str.end(); i++) {
char ch;
ris >> ch;
if (ch != *i) {
ris.setstate(ios::failbit);
return ris;
}
}
return ris;
}
};


char Peek();
istream &operator >> (istream&, skip);

double EvaluateSubExpression();
double EvaluateFirstOperand();
double EvaluateExpression(char);


char Peek() {
return (cin >> ws).peek();
}

istream &operator >> (istream &ris, skip s) {
return s(ris);
}


double EvaluateSubExpression() {
cin >> ws >> skip("(");
return EvaluateExpression(')');
}

double EvaluateFirstOperand() {
if (Peek() != '(') {
double f;
cin >> f;
return f;
} else {
return EvaluateSubExpression();
}
}

double EvaluateExpression(char chTerminator) {
double fFirstOperand = EvaluateFirstOperand();

char ch;
cin >> ws >> ch;
switch (ch) {
case '+':
return fFirstOperand + EvaluateExpression(chTerminator);
case '-':
return fFirstOperand - EvaluateExpression(chTerminator);
case '*':
return fFirstOperand * EvaluateExpression(chTerminator);
case '/':
return fFirstOperand / EvaluateExpression(chTerminator);
default:
cin.putback(ch);
cin >> skip(chTerminator);
return fFirstOperand;
}
}


int main() {
cin.exceptions(ios::failbit | ios::badbit);
try {
while (true) {
cout << "\t" << EvaluateExpression('=') << endl;
}
} catch (ios::failure &e) {
cerr << "input non valido" << endl;
}
return 0;
}


questa versione non tiene conto della precedenza degli operatori, esegue le operazioni sempre da destra verso sinistra; l'unico modo per farle capire la giusta precedenza é esplicitare le parentesi.

l'ho sviluppata seguendo questa sintassi:
expression ::= first-operand [OPERATOR expression]

first-operand ::= NUMBER |
sub-expression

sub-expression ::= '(' expression ')'

la semantica é ovvia. sicuramente é possibile definire una sintassi che permetta di eseguire le operazioni nell'ordine giusto ma ora non mi va.

fero86
25-03-2010, 16:46
P.S:mi resta cmq una domanda è possibile lavorare con più linguaggi in un solo progetto? questa domanda posta cosi in generale non ha senso; spesso é possibile, ma dipende dalle tecnologie che usi. per esempio se lavori in .NET é possibile creare un programma scritto in piu d'uno dei linguaggi della piattaforma (C#, Basic, F#, Managed C++), ed inoltre é possibile che quel programma usi una DLL scritta in qualunque altro linguaggio.

pspmaniaco
26-03-2010, 21:50
questa domanda posta cosi in generale non ha senso; spesso é possibile, ma dipende dalle tecnologie che usi. per esempio se lavori in .NET é possibile creare un programma scritto in piu d'uno dei linguaggi della piattaforma (C#, Basic, F#, Managed C++), ed inoltre é possibile che quel programma usi una DLL scritta in qualunque altro linguaggio.

Perfetto volevo sapere questo ora mi studio c++ e c# e poi vedo l'ambiente + utile ai miei scopi,grz di tutto :)

fero86
29-03-2010, 22:59
riesumo il topic per di che oggi ho avuto tempo di scrivere in C++ una calcolatrice per le quattro operazioni che rispetta l'ordine di precedenza degli operatori e ammette anche le parentesi tonde:

#include <iostream>
using namespace std;


char Peek();
void Skip(char ch);

double EvaluateOperand();
double EvaluateProduct();
double EvaluateExpression();


int main() {
cin.exceptions(ios::failbit | ios::eofbit | ios::badbit);
try {
while (true) {
cout << '\t' << EvaluateExpression() << endl;
Skip('=');
}
} catch (const ios::failure&) {
cerr << "invalid input." << endl;
}
return 0;
}


char Peek() {
return (cin >> ws).peek();
}

void Skip(char ch) {
if (Peek() != ch) {
cin.setstate(ios::failbit);
}
cin.get();
}


double EvaluateOperand() {
if (Peek() != '(') {
double f;
cin >> f;
return f;
} else {
cin.get();
double f = EvaluateExpression();
Skip(')');
return f;
}
}

double EvaluateProduct() {
double f = EvaluateOperand();
char ch = Peek();
if (ch == '*') {
cin.get();
return f * EvaluateProduct();
} else if (ch == '/') {
cin.get();
return f / EvaluateProduct();
} else {
return f;
}
}

double EvaluateExpression() {
double f = EvaluateProduct();
char ch = Peek();
if (ch == '+') {
cin.get();
return f + EvaluateExpression();
} else if (ch == '-') {
cin.get();
return f - EvaluateExpression();
} else {
return f;
}
}




é basata su questa sintassi:
expression ::= product [ ( '+' | '-' ) expression ]
product ::= operand [ ( '*' | '/' ) product ]
operand ::= VALUE |
sub-expression
sub-expression ::= '(' expression ')'



spero sia utile.