Prosta aplikacja sieciowa - przesyłanie wyników

0

Witam, mam do uzupełnienia kod i moje zadanie polega na:
"Zmodyfikuj program serwera, tak aby po otrzymaniu ramki danych: „d 123 21” program dodał dwie liczby 123 i 21, a następnie odesłał wynik do klienta. Komenda „o” powinna odejmować dwie liczby."

I mój fragment kodu to tego wygląda tak:

 
	int i = 2, result = 0;
		int a, b, c;
		if (server.recvbuf[0] == 'd')
		{
			while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
			{
				result = server.recvbuf[i] - 48 - result * 10;//'1'-48, zeby przeksztalcic asci na liczbe, pod result poprzednia 
				i++;
			}
			a = result;
			i += 1;
			result = 0;
			while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
			{
				result = server.recvbuf[i] - 48 - result * 10;
				i++;
			}
			b = result;
			c = a + b;
			cout << c << endl;
		}

Niestety w wyniku, w drugim okienku wypisuje zły wynik, np jeśli piszę "d 21 27" to otrzymam "-32"
Ma ktoś może pomysł co mi się upsuło?

5
  1. server.recvbuf[i] - 48 - result * 10; czemu odejmujesz poprzedni wynik?
  2. Czemu używasz magicznych liczb? '0' zamiast 48
  3. Dlaczego sobie nie ułatwisz zadania i nie użyjesz streamów?
  4. Dlaczego wypisujesz na ekran zamiast odesłać wynik klientowi
  5. Zakładasz, że na początku bufora będzie literka. Nie planujesz obsługi kilku żądań w kolejnych liniach?
0

Na laborkach gościu coś mówił, że tyle należy odjąć, żeby z ASCI się zgadzało jakoś. No i faktycznie 0 w ASCI jest pod nr 48, więc pewnie temu tak.
Do tego '0' zamiast 48 to mowisz o pętli, tak? I o tym, że można by

while (server.recvbuf[i] >=48 && server.recvbuf[i] <= 57) 

?
Na razie wypisuje na ekran, bo chce zobaczyć czy działa okej, a jak będzie działać to odeślę wynik, ale no właśnie najpierw to musi dobrze zliczać.
Ogl ten kod co mamy jest trochę dziurawy, bo to wygląda tak, że klient może wpisać linijkę tekstu, odsyła serwerowi, na serwerze można wpisać linijke i odsyla klientowi. Ale klient np nie może dwóch linijek wpisać, ino jedną zawsze...

0

kq już zwrócił na to uwagę - dlaczego w linii:
result = server.recvbuf[i] - 48 /* --> */ - /* <-- /* result * 10;
jest odejmowanie w zaznaczonym miejscu?

0

No to jak inaczej przejść z asci na cyfry? Bo nie mam konceptu? Bo raczej tak o:

result = server.recvbuf[i] * 10; 

nie może być?

0

Punkt trzeci: dlaczego nie użyjesz streamów?

0

Mówisz o strumieniach wejścia/wyjścia? Raczej o czymś innym. Nie pokazywali nam, że tu można pójść inną drogą ;x

2

Jeśli samodzielne zdobywanie wiedzy jest zakazane to biada naszemu systemowi edukacji.

auto main() -> int
{
	string s = "d 234 432";
	stringstream ss{s};
	char op;
	int p1, p2;
	ss >> op >> p1 >> p2;
	DBG(op);
	DBG(p1);
	DBG(p2);
	DBG(p1+p2);
}

http://melpon.org/wandbox/permlink/bKPNKJozm2sJyMf0

0

W sumie i w tamtym udało mi sie znaleźć błąd ot powinno być

 result = server.recvbuf[i] - 48 + result * 10;

Xupicor miał rację, coś zaćmienie chyba mam.
Kwestia durnego znaku, ghrrr

0

A jeszcze jedno w sumie, teraz chce to tak przerobić, żeby dodawał lub odejmował trzy liczby po otrzymaniu ramki danych w postaci: „123+12+21” lub „12-4-9”.
No i wygląda to u mnie jakoś tak:

//Funkcja dodajaca/odejmujaca trzy liczby 
		int i = 0, result = 0;
		int a = 0, b = 0, c = 0, d = 0;
		if (server.recvbuf[0] >= '0' && server.recvbuf[0] <= '9')
		{
			while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
			{
				result = server.recvbuf[i] - 48 + result * 10;//'1'-48, zeby przeksztalcic asci na liczbe, pod result poprzednia 
				i++;
			}
			a = result;
			result = 0;

			if (server.recvbuf[i] == '+')
			{
				while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
				{
					result = server.recvbuf[i] - 48 + result * 10;
					i++;
				}
				b = result;
				result = 0;
				i += 1;

				while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
				{
					result = server.recvbuf[i] - 48 + result * 10;
					i++;
				}
				c = result;
				d = a + b + c;
			}

			else if (server.recvbuf[i] == '-')
			{
				while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
				{
					result = server.recvbuf[i] - 48 + result * 10;
					i++;
				}
				b = result;
				result = 0;
				i += 1;

				while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
				{
					result = server.recvbuf[i] - 48 + result * 10;
					i++;
				}
				c = result;
				d = a - b - c;
			}

		}
 

I dla dwóch liczb to działa, ale dla trzech się sypie...
I jeśli się przebada jak to leci to w sumie jeśli się by wpisało np "5+2+7" to dla a przypisze 5, dla b przypisze 0, a dla c przypisze 2.
Tylko w sumie nie mam koncepcji jak to ruszyć i wiem, że te dwa while w ifie to tak być nie może ;x

2

Dlaczego tak kombinujesz jak koń pod górę? Masz wyżej przykład wygodnego wczytywania...

0

No tak, ale to potrzebuje jakiejś dodatkowej biblioteki? Bo DBG i ss mi podkreśla.

1

DBG to moje makro do wygodnego pokazywania wartości zmiennych w przykładach.

stringstream jest w <sstream>

0

Okej, dzięki ;)

1

Jeśli zamierzasz iść w kierunku obsługiwania nawiasów i pierwszeństwa operatorów, to myślę, że lepiej od razu pójść w shunting-yard i RPN/AST niż rozbudowywać warunki w taki sposób. ;)

0

Podbijam.
Teraz chcę zrobić coś takiego, żeby można było dodawać/odejmować nieokreśloną liczbę liczb np 11+12-20+26.
Więc stringami już chyba nie za bardzo. Na razie udalo mi się napisac coś takiego o:

	int i = 0, result = 0;
		int  c=0;
		while (server.recvbuf[i]>='+' && server.recvbuf[i]<='9')
		{
			while (server.recvbuf[i] >= '0' && server.recvbuf[i] <= '9')
			{
				result = server.recvbuf[i] - 48 + result * 10;//'1'-48, zeby przeksztalcic asci na liczbe, pod result poprzednia 
				i++;
			}
			
			if (server.recvbuf[i] == '+')
			{
				c += result;
				result = 0;
				i++;
			}
			else if (server.recvbuf[i] == '-')
			{
				c -= result;
				result = 0;
				i++;
			}
			
		}
 

Tylko to mi zawsze zwróci tylko pierwszą liczbę. Ma ktoś może pomysł co nie tak albo jaką inną drogą pójść?

0
Skipper11 napisał(a):

Podbijam.
Teraz chcę zrobić coś takiego, żeby można było dodawać/odejmować nieokreśloną liczbę liczb np 11+12-20+26.
Więc stringami już chyba nie za bardzo.

Czemu nie? Robisz w pętli coś takiego (zakładam, że wszystko kończy się spacją, jak nie, to zmień warunek/konstrukcję pętli):

s >> wynik;
s >> znak;
while(znak != ' ') {
  s >> liczba;
  if(znak == '+')
    wynik += liczba;
  else if(znak == '-')
    wynik -= liczba;
  else
    // tu jakaś obsługa czegoś złego, co nie powinno być
  s >> znak;
}

Oczywiście zadziała tylko dla operatorów o równym priorytecie, łącznych lewostronnie (tak jest dla +-, tak też jest dla */, ale już nie jak je pomieszasz). Jak masz jakieś inne, to buduj parser. :) Aha, i nie testowałem, mogłem coś przeoczyć... :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1