Gjest Slettet-aNZFa3 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 (endret) Klikk for å se/fjerne innholdet nedenfor public void Compile(string Code) { try { string sCode = @" using System; using System.Windows.Forms; class Calc { public void Main() { MessageBox.Show(Convert.ToString(" + Code + @")); } }"; CSharpCodeProvider codeProvider = new CSharpCodeProvider(); ICodeCompiler compiler = codeProvider.CreateCompiler(); CompilerParameters parameters = new CompilerParameters(); parameters.GenerateExecutable = false; parameters.GenerateInMemory = true; parameters.MainClass = "Calc.Main"; parameters.IncludeDebugInformation = false; foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { parameters.ReferencedAssemblies.Add(asm.Location); } CompilerResults results = compiler.CompileAssemblyFromSource(parameters, sCode); object o = results.CompiledAssembly.CreateInstance("Calc"); Type type = o.GetType(); MethodInfo m = type.GetMethod("Main"); m.Invoke(o, null); } catch { } } Jeg har nesten samme koden i et annet programm, men der bruker jeg koden til dynamisk kode visning, egentlig bare for moro skyld. Kort oppsummert av kalkulatoren: Den henter ut teksten fra en tekstboks, når det blir trykket på en knapp, den teksten blir da "matet" inn i funksjonen som da viser svaret i en MessageBox. Spørsmål: Hvor avansert er det å lage en bool funksjon som verifisere teksten som et regnestykket? Er det bare å prøve å kompilere den koden og returnere true hvis det gikk bra, og false hvis det er noen feilmeldinger? EDIT: koden den funker den. Endret 2. januar 2009 av Slettet-aNZFa3 Lenke til kommentar
hockey500 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 okei, wtf? Så la meg bare få dette helt rett: du har en tekstboks, som for eksempel inneholder teksten "2+4" eller "3*6", og den koden der bruker du for å få svaret til å poppe opp i en tekstboks? Jeg håper virkelig jeg har misforstått noe kraftig, for det der må være den dårligste, treigeste, mest håpløse løsningen på et slikt problem du kunne funnet på. Lenke til kommentar
Gjest Slettet-aNZFa3 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 Jaha, og hvordan ville du ha gjort det da? Eneste måten jeg fant ut var å kompilere kode dynamisk. Lenke til kommentar
hockey500 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 (endret) er det så enkelt at du bare har "a+b", "a-b", "a*b" eller "a/b" ville jeg kanskje gjort noe slikt: class Program { public delegate double MyDelegate(double a, double b); static void Main(string[] args) { string math = "2 - 3"; Console.WriteLine(Parse(math)); math = "12432*234234"; Console.WriteLine(Parse(math)); math = "1345 / 123542"; Console.WriteLine(Parse(math)); Console.Read(); } static double Parse(string math) { string pattern = @"^\s*(?<a>\d+)\s*(?<operator>(\+|\-|\*|\/))\s*(?<b>\d+)\s*$"; if (Regex.IsMatch(math, pattern, RegexOptions.IgnorePatternWhitespace)) { Match match = Regex.Match(math, pattern, RegexOptions.IgnorePatternWhitespace); MyDelegate del = GetDelegate(match.Groups["operator"].Value); return del(double.Parse(match.Groups["a"].Value), double.Parse(match.Groups["b"].Value)); } else throw new Exception("parameter doesn't seem valid"); } static MyDelegate GetDelegate(string op) { switch (op) { case "+": return new MyDelegate(Add); case "-": return new MyDelegate(Subtract); case "*": return new MyDelegate(Multiply); case "/": return new MyDelegate(Divide); default: throw new Exception("Invalid operator"); } } static double Add(double a, double b) { return a + b; } static double Subtract(double a, double b) { return a - b; } static double Multiply(double a, double b) { return a * b; } static double Divide(double a, double b) { if(b != 0) return (a / b); throw new DivideByZeroException(); } } dog, det er heller ingen god løsning hvis problemet ikke alltid er så statisk. PS: jeg tok meg friheten å sammenlikne ytelsen, denne løsningen var ca 7000 ganger raskere på 100 parsinger. og enda en PS: du skal ha credit for kreativitet, løsningen var om ikke annet svært original. og en ting til, du kjører vel en form for validering av tekstboksinnholdet? hvem som helst kan jo skrive C#-kode der som kan kjøres av programmet ditt, kanskje ikke det smarteste. Endret 2. januar 2009 av hockey500 Lenke til kommentar
Gjest Slettet-aNZFa3 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 (endret) Jeg har også med sin, cos, tan og log. Koden min så kan man regne ut lange regnestykker (men treigt). Eks: 2+2*(Cos(3)/Tan(2))+5*10 , den funker den, men Texas Kalkulatoren min er mye raskere. Men skal prøve koden din seinere idag, og modifisere den til mitt bruk. Jeg har mye igjen å lære, og jeg stopper vel heller ikke å lære. Jeg har endel kode til (med tan, sin cos etc), men den er egentlig ikke så relevant for saken akkuratt nå. Endret 2. januar 2009 av Slettet-aNZFa3 Lenke til kommentar
hockey500 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 Skal du kunne parse sånne uttrykk ville jeg ikke satset på verken min eller din løsning. da trenger du en helt annen tilnærming til problemet. Tror faktisk det nylig ble diskutert her på forumet, det var en fyr som spurte om forslag til hva han kunne lage i IT2 på VGS, en kalkulator som parser slike uttrykk ble da foreslått. Du kan kanskje starte med å lese hva som ble sagt der. Eller du kan fortsette med din metode, som forsåvidt funker greit, så lenge du forsikrer deg om at det ikke skrives inn kode i input og du ikke bryr deg om ytelse. Lenke til kommentar
GeirGrusom Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 (endret) Mitt forslag til utbedring er å hente ut den innerste parentesen, deretter lage en liste over instruksjoner som du sorterer etter operator, og utfører, og repeat. Det er normal praksis at ( dytter akkumulatorverdien til stack, og ) henter den tilbake.Koden til hockey500 tar ikke hensyn til operator presedens eller parantes. Compileren er treg, som vel er eneste ulempen. 10 + 20 * 30 + ( 40 - 50 ) som kan sees slik 20 * 30 + 10 + ( 40 - 50 ) add 20 mul 30 add 10 push add 40 sub 50 add pop edit: og bytt fra double til decimal. Når det gjelder C# compileren til kalkulator kan det være en god idé å alltid legge til return først, slik at koden alltid havner på maks én linje. Sånn det er gjort nå, så kan hvem som helst gjøre hva som helst. Endret 2. januar 2009 av GeirGrusom Lenke til kommentar
Gjest Slettet-aNZFa3 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 En løsning til er jo å opprette et .vbs skript, og så kjøre den. Jeg leste i den andre tråden, og kom fram til at jeg kunne prøve å få til reversed polish notation. Lenke til kommentar
GeirGrusom Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 Sant. Dette er en forholdsvis vanskelig prosess, så lykke til da Lenke til kommentar
Gjest Slettet-aNZFa3 Skrevet 2. januar 2009 Del Skrevet 2. januar 2009 Det med et .vbs skript fungere perfekt, rask var den også (raskere). Men jeg skal fortsatt ta en titt på reverse polish notation. 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å