Dit lijkt te werken alleen zie ik nu steeds dat als input 0 wordt afgedrukt.D
Denk dat dit door de enter komt.
Hoe kan ik dit oplossen ?
Code :
void setup() {
Serial.begin(9600);
}
void loop() {
// input some mumber and it gets parsed to a nummmer
Serial.print("Mag ik het eerste getal");
// wachtenn op de input
while (Serial.available() == 0) {}
int getal = Serial.parseInt();
Serial.println(getal);
}
Die extra 0 is zeer waarschijnlijk het resultaat van een linefeed <LF> of carriage return <CR> die de seriële monitor in wokwi stuurt en aangezien dat geen nummer tussen 0 en 9 is wordt er 0 van gemaakt.
Je moet dus testen of het ontvangen karakter inderdaad een numerieke waarde is.
Je kunt Robin's updated Serial Input Basics eens lezen om wat ideeën te krijgen hoe je seriële invoer kunt afhandelen.
Hoe weet ik of het een getal, een + of een = is
En ga ik alles parsen naar de polish methode of gebruik ik 2 stacks om te parsen en dan alles uit te rekenen.
Elk teken heeft een eigen ASCII code.
Je moet dus niet op zoek gaan naar de 1 of de +, maar naar 49 (0x31) of 43 (0x2B).
De getallen die als 0x.. worden geschreven zijn hexadecimale getallen die dezelfde waarde hebben als de decimale getallen.
Je kunt deze tekens opzoeken in een ASCII tabel (klik !), daar zijn er een heleboel van te vinden dus zoek er 1 op die je handig vindt om te gebruiken.
Het is dus raadzaam om alle ASCII tekens die binnenkomen maar die je niet wil gebruiken, weg te gooien en daarmee jezelf een beetje hoofdzorgen te besparen.
Misschien wil je nog wel 3 tekens extra gebruiken, eentje die enter vertegenwoordigt om de berekening te starten, eentje die je in staat stelt het laatste teken dat je (dan per ongeluk) hebt ingegeven weer wist (de C op je calculator), en eentje dat alles weer naar nul zet (de CE op je calculator).
Wanneer je tekens binnen hebt gekregen die je wel wil gebruiken, zul je die alsnog moeten omzetten, eerst naar losse cijfers, en dan naar getallen of operators voor je rekenmachine.
Je kunt ieder binnengekomen karakter testen. Als je een 0 invoert wordt het karakter '0' gestuurd, voor 1 wordt het karakter '1' gestuurd enz. Voor een + wordt het karakter '+' gestuurd.
Om te controleren of een karakter een nummer is kun je een simple if gebruiken waar je een reeks test; ch in onderstaand voorbeeld is een enkel karakter dat je ingelzen hebt met Serial.read().
if (ch >= '0' && ch <= '9')
{
// het is een nummer
}
else
{
// het is geen nummer
}
Er is ook een standaard functie isDigit() die hetzelfde doet.
Om te controleren welke wiskundige functie uitgevoerd moet worden kun je een simpele if gebruiken. B.v.
if (ch == '+')
{
// plus ontvangen
}
Als je een nummer ontvangt kun je dat toevoegen aan een array zodat je dat later kunt omzetten naar een integer of float.
Er zijn wat probleem met het bovenstaande.
Als je floating point getallen wilt invoeren moet je de decimale punt (komma) ook afhandelen.
Een '-' kan niet alleen een bewerking aanduiden maar ook een negatief getal.
Voor later:
Ik denk dat de beste oplossing is om een kleine finite state machine (FSM) te gebruiken die bijhoudt wat je aan het invoeren bent
Lees eerste getal (met bv Robin's tweede voorbeeld).
Test if het een getal is. Indien ja, ga naar het lezen van het tweede getal.
Lees het tweede getal.
Test of het een getal is. Indien ja, ga naar het lezen van de bewerking
Voor wat ik begrepen heb, is het de bedoeling dat de bewerking complex gemaakt wordt en dat er dan toch de juiste rekenmethode wordt gebruikt, vandaar de Meneer van Dalen.
Daarmee is de laatst genoemde handelswijze een begin, maar niet hetgeen wat uiteindelijk de bedoeling is.
Aan de hand van die handelswijze, is overigens wel een iets gewijzigde variant te bedenken, namelijk afwisseling van getal en bewerking, waarbij het gelijk aan teken dan het geheel afsluit en het resultaat getoond kan worden.
Moet je dan je operators stack niet ook nog gaan beheren om de prioriteiten juist te krijgen ?
Of ga je niet meer dan 3 getallen en 2 operators toestaan ?
Klinkt eenvoudig maar het is geen stack (LIFO). Als je 3 * 4 + 2 wilt berekenen zul je niet de laatste invoer van de stack moeten halen maar de eerste invoer zodat je de vermenigvuldiging kunt doen voor de optelling.
Ik weet niet of er eenvoudigere oplossing zijn; nooit over nagedacht.
Wil je ook het gebruik van haakjes wilt toestaan zoals in (2+3) * 4? En/of machtsverheffen en worteltrekken?