Kargan Skrevet 8. mai 2008 Del Skrevet 8. mai 2008 Får compalia og starta programme, men når jeg setter f,eks R=2k l=2m c=2p så takler den det på en rar måte. Har sotte i en stund med feilen, men finner ikke noen orsak. r=2k l=2m c=2p <<-- Indata 2K L 2P 2M C=2P double inndata(bool kjor,vector<double> &motstand, vector<double> &spole, vector<double> &kondensator) { double r = 0; double l = 0; double c = 0; int i = 0; int pos = 0; int pos2 = 0; string data, temp; getline(cin, data); for(int i=0;i<data.length();i++) // Gjør alle bokstaver store, og bytter comma med punktom { char tegn; tegn = data; if(tegn == ',') tegn = '.'; data = toupper(tegn); //bytter lowerchar med upperchar } if(data == "STOP" || data == "" || data == " ") return false; //Deler opp stringene til forskjellige deler R, C og L if(data.find("R=") != -1) { pos = data.find("R=",0) + 2; pos2 = data.find(" ",pos); temp = data.substr(pos,pos2); //Finner ut hvordan verid den skal sette inn om det angitt med K eller M if(temp.find("K",0) != -1) r += atof(temp.c_str()) * 1000; else if(temp.find("M",0) != -1) r += atof(temp.c_str()) * 1E6; else {r += atof(temp.c_str());} cout << temp << endl; temp.erase(); } if(data.find("C=") != -1) { pos = data.find("C=",0) + 2; pos2 = data.find(" ",pos) ; temp = data.substr(pos,pos2); //Finner ut hvordan verdi den skal sette inn om det er angitt i p,u eller m if(temp.find("P",0) != -1) c = atof(temp.c_str()) * 1E-12; else if(temp.find("N",0) != -1) c = atof(temp.c_str()) * 1E-9; else if(temp.find("U",0) != -1) c = atof(temp.c_str()) * 1E-6; else if(temp.find("M",0) != -1) c = atof(temp.c_str()) * 1E-3; else {c = atof(temp.c_str());} cout << temp << endl; temp.erase(); } if(data.find("L=") != -1) { pos = data.find("L=",0) + 2; pos2 = data.find(" ",pos) ; temp = data.substr(pos,pos2); //Finner ut hvordan verdi den skal sette inn om det er angitt i p,u eller m if(temp.find("P",0) != -1) l = atof(temp.c_str()) * 1E-12; else if(temp.find("N",0) != -1) l = atof(temp.c_str()) * 1E-9; else if(temp.find("U",0) != -1) l = atof(temp.c_str()) * 1E-6; else if(temp.find("M",0) != -1) l = atof(temp.c_str()) * 1E-3; else {l = atof(temp.c_str());} cout << temp <<endl; temp.erase(); } cout << "M: " << r << " L: " << l << " C: " << c << endl; motstand.push_back®; spole.push_back(l); kondensator.push_back©; } Lenke til kommentar
ToMmM Skrevet 8. mai 2008 Del Skrevet 8. mai 2008 Kan du laste opp hele koden så jeg kan teste den? Lenke til kommentar
teflonpanne Skrevet 8. mai 2008 Del Skrevet 8. mai 2008 (endret) Hm, du hadde litt rotete kode, ikke så lett å se hva som kan være galt, spesielt når du ikke skriver hva som er galt en gang.. Jeg skrev uansett en parser i C du kan se på, den funker. #include <stdio.h> #include <stdbool.h> #include <stdlib.h> char op = '='; enum token { r, k, l, undefined }; enum number { K = 1000, M = 1000000, nan }; char *str; typedef enum token token; typedef enum number number; bool get_op(); token get_token(); number get_num(); int expr(); int main() { str = (char *)malloc(100); printf("> "); fgets(str, 100, stdin); /* leser helt til expr returnerer 0 */ while (expr()) { *str++; /* leser en ekstra space på slutten av et uttrykk */ } if (*str != 0) printf("error: %c\n", *str); } int expr() { char pre; /* holder tallet foran konstanten, f.eks 2 i 2K */ double res; /* resultatet */ token t = get_token(); /* få tak i neste token */ if (t == undefined) return 0; /* returner 0 hvis tokenet ikke er r, k eller l */ if (!get_op()) return 0; /* returner 0 hvis vi ikke finner en = etter tokenet */ pre = *str++; /* få tak i tallet */ res = atof((char*)&pre); /* konverter til float og sett til res */ number n = get_num(); /* få tak i en konstant */ if (n == nan) return 0; /* sjekk at konstanten er K eller M */ res *= n; /* gang resultatet med konstanten */ switch (t) { /* ferdig */ case r: { printf("%c = %f\n", 'r', res); break; } case k: { printf("%c = %f\n", 'k', res); break; } case l: { printf("%c = %f\n", 'l', res); break; } } return 1; } bool get_op() { char op = *str++; return (op == '=') ? true : false; } token get_token() { token tok; int t = *str++; switch (t) { case 'r': { tok = r; break; } case 'k': { tok = k; break; } case 'l': { tok = l; break; } default: tok = undefined; } return tok; } number get_num() { number num; char n = *str++; switch (n) { case 'K': { num = K; break; } case 'M': { num = M; break; } default: num = nan; } return num; } $ gcc parser.c $ ./a.out > r=2K l=3M r = 2000.000000 l = 3000000.000000 $ Tok ikke med alle konstantene dine da, men det klarer du sikkert. Endret 8. mai 2008 av teflonpanne Lenke til kommentar
Kargan Skrevet 8. mai 2008 Forfatter Del Skrevet 8. mai 2008 Kan du laste opp hele koden så jeg kan teste den? Jeg skal lage et programm som jeg kan bruke til og regne ut faseforkyviner, impdangs osv. Der kommer forkortelsene fra. // J Omega - Take 1 #include <iostream> #include <vector> #include <cstdlib> #include <string> #include <cctype> #include <cmath> using namespace std; double inndata(bool kjor,vector<double> &motstand, vector<double> &spole, vector<double> &kondensator); //Prototype for innlesning av verdier int utregningsmetode(vector<double> &motstand, vector<double> &spole, vector<double> &kondensator,int i); // utrening av basert på datan som er oppgitt double kunnr(vector<double> motstand, double spenning, int i); int main() { vector<double> motstand; vector<double> spole; vector<double> kondensator; bool kjor = true; int i = 0; int valg = 1; int ganger = 0; double hz = 0; double spenning = 0; double stromtotr = 0; cout << "\nTast inn verider du vil bruke i bergningen\n"; cout << "En kan bruke boksav bevniner som M, k, m, u, n og p\n"; cout << "F,eks : R=1k C=2u L=2m\n"; cout << "skriv 'stop' eller tom rom for og stoppe innlesning\n"; while(true) { kjor = inndata(kjor,motstand,spole,kondensator); //Funksjonskall av innlesning av data til utregningen if(kjor == false) break; // Fortsette eller stoppe og samle inn data cout << "M:" << motstand[i] << " L:" << spole[i] << " C:" << kondensator[i] << endl; i++; } //skjekker om det skal kjøres utreninger if(motstand.empty() == true && spole.empty() == true && kondensator.empty() == true) { cout << "Ingen verider programme avlsutter\n"; return 0; } cout << "Spenning?\n"; cin >> spenning; //Sjekker åssen matte formel som skal brukes for(i=0;i<motstand.size();i++) { valg = utregningsmetode(motstand,spole,kondensator,i); if(valg == 1) stromtotr += kunnr(motstand,spenning,i); else if(valg == 2) cout << "Det er spole i krestsen kekek\n"; else if(valg == 3) cout << "Det er kondensator i kretsen kekekek\n"; } cout << "Total strømmen blir " << stromtotr << " A" << endl; } double kunnr(vector<double> motstand, double spenning, int i) { double strom = 0; strom = spenning / motstand[i]; cout << "Srømmen i grenn nr "<< i+1 << " " << strom << " A" << endl; return strom; } int utregningsmetode(vector<double> &motstand, vector<double> &spole, vector<double> &kondensator, int i) { int valg = 0; if(motstand[i] > 0 && spole[i] == 0 && kondensator[i] == 0 ) valg = 1; // R else if(motstand[i] == 0 && spole[i] > 0 && kondensator[i] == 0) valg = 2; // L else if(motstand[i] == 0 && spole[i] == 0 && kondensator[i] > 0) valg = 3; // C else if(motstand[i] > 0 && spole[i] > 0 && kondensator[i] == 0) valg = 4; // R + L else if(motstand[i] == 0 && spole[i] > 0 && kondensator[i] > 0) valg = 5; // C + L else if(motstand[i] > 0 && spole[i] == 0 && kondensator[i] > 0) valg = 6; // R + C else if(motstand[i] > 0 && spole[i] > 0 && kondensator[i] > 0) valg = 7; // Skjekker om alle verider er satt return valg; } double inndata(bool kjor,vector<double> &motstand, vector<double> &spole, vector<double> &kondensator) { double r = 0; double l = 0; double c = 0; int i = 0; int pos = 0; int pos2 = 0; string data, temp; getline(cin, data); for(int i=0;i<data.length();i++) // Gjør alle bokstaver store, og bytter comma med punktom { char tegn; tegn = data[i]; if(tegn == ',') tegn = '.'; data[i] = toupper(tegn); //bytter lowerchar med upperchar } if(data == "STOP" || data == "" || data == " ") return false; //Deler opp stringene til forskjellige deler R, C og L if(data.find("R=") != -1) { pos = data.find("R=",0) + 2; pos2 = data.find(" ",pos); temp = data.substr(pos,pos2); //Finner ut hvordan verid den skal sette inn om det angitt med K eller M if(temp.find("K",0) != -1) r += atof(temp.c_str()) * 1000; else if(temp.find("M",0) != -1) r += atof(temp.c_str()) * 1E6; else {r += atof(temp.c_str());} cout << temp << endl; temp.erase(); } if(data.find("C=") != -1) { pos = data.find("C=",0) + 2; pos2 = data.find(" ",pos); temp = data.substr(pos,pos2); //Finner ut hvordan verdi den skal sette inn om det er angitt i p,u eller m if(temp.find("P",0) != -1) c = atof(temp.c_str()) * 1E-12; else if(temp.find("N",0) != -1) c = atof(temp.c_str()) * 1E-9; else if(temp.find("U",0) != -1) c = atof(temp.c_str()) * 1E-6; else if(temp.find("M",0) != -1) c = atof(temp.c_str()) * 1E-3; else {c = atof(temp.c_str());} cout << temp << endl; temp.erase(); } if(data.find("L=") != -1) { pos = data.find("L=",0) + 2; pos2 = data.find(" ",pos); temp = data.substr(pos,pos2); //Finner ut hvordan verdi den skal sette inn om det er angitt i p,u eller m if(temp.find("P",0) != -1) l = atof(temp.c_str()) * 1E-12; else if(temp.find("N",0) != -1) l = atof(temp.c_str()) * 1E-9; else if(temp.find("U",0) != -1) l = atof(temp.c_str()) * 1E-6; else if(temp.find("M",0) != -1) l = atof(temp.c_str()) * 1E-3; else {l = atof(temp.c_str());} cout << temp <<endl; temp.erase(); } motstand.push_back(r); spole.push_back(l); kondensator.push_back(c); } Lenke til kommentar
teflonpanne Skrevet 9. mai 2008 Del Skrevet 9. mai 2008 (endret) Fikk du det til? Kan gi deg et lite tips om at du burde skrive om hele den funksjonen din. Du traverserer strengen gaaanske mange ganger En gang på starten for å konvertere case, og så bruker du find uhorvelig mye. Hver gang du kaller find søker du gjennom strengen på nytt. I mitt eksempel går jeg gjennom strengen en gang. Det betyr ikke så mye i et sånt lite program, men det er greit å vite sånn at du ikke skriver sånn kode i større programmer. Da får du ganske alvorlige flaskehalser. Så du burde bare gå gjennom strengen en bokstav om gangen. Sjekk om den første er en av r,k eller l, deretter forventer du et likhetstegn, så et tall og så en bokstav K,M,N,P osv. Når du har kommet til den siste bokstaven vet du at det skal være et mellomrom og så begynner sekvensen på nytt igjen. I tillegg til å bli veldig mye raskere gir det også mer lesbar og strukturert kode. Lykke til Endret 9. mai 2008 av teflonpanne Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå