Jump to content


Check out our Community Blogs

Register and join over 40,000 other developers!


Recent Status Updates

View All Updates

Photo
- - - - -

[Solved][Assignment] Awesome Calculator Help

calculator

  • Please log in to reply
5 replies to this topic

#1 notes

notes

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Location:Poland
  • Programming Language:C++
  • Learning:Java, C#

Posted 15 May 2012 - 10:40 AM

Hi,

I have assignment to make for my client- server programming classes.

Subject : Internet calculator.
Client sends equation as a string, server sends response (string ) with result. More complex equation is server gives higher grade for equation.



I have client and server structure done and its working - sending and receiving strings (through winsock).

I need help with choosing what kind of string to send and how to analyze it on server side.
Basically I want client side to be written in visual c++ forms something look alike calculator with only defined operations as buttons - to prevent sending bugged strings by client. String will look like " 23-2*33 ". The problem starts when I want to add something more complex like : " sqrt(2*2) ". How to make my server firstly do multiplication then exponentiation ? Any ideas ? Where to look ?


Regards,
notes.
  • 0
Remebre about KISS & DRY

#2 gregwarner

gregwarner

    Obi Wan of Programming

  • Expert Member
  • PipPipPipPipPipPipPip
  • 1586 posts
  • Location:Arkansas
  • Programming Language:C, Java, C++, C#, PHP, Transact-SQL

Posted 15 May 2012 - 10:53 AM

Step 1: Scan your string for tokens. (This step also detects invalid characters and tokens.)

Step 2: Parse your tokens and build a parse tree. (This step also detects invalid parsings, or arrangements of tokens. e.g., "20 +" would be flagged as invalid here.)

Step 3: Traverse the parse tree and evaluate the equation.

Tokens like "sqrt" are stored in a lookup table, and when you scan a token, you check it against those in the lookup table to see if it is a defined word.
  • 0

ti-99-sig.png
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
– Douglas Hofstadter, Gödel, Escher, Bach: An Eternal Golden Braid


#3 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 15 May 2012 - 07:32 PM

gregwarner is right. In addition, I think can you convert the infix expression to prefix/postfix and evaluate it.
  • 0

#4 notes

notes

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Location:Poland
  • Programming Language:C++
  • Learning:Java, C#

Posted 28 May 2012 - 11:38 AM

Thanks. I've got RPN ( postfix) client - server calculator working with ( ) * / + - ^ on command line. Now I wanted to make some graphic layout ( windows forms ) in Visual Studio 2010 But seems that MS dropped intellisense for C++/CLI(function that shows avialable methods and variables for an object[ctrl + space] ) which makes writing app much harder for me. Now I wonder Is there any way ( plugin or something ) to install it ? Else If I have all my code written in c++ and now I will have to use c# to write graphic layout will I have to rebuild my code from a start ? How much c# is compatible with c++ code ?

Thanks.


EDIT :

I have made layout in c# but now I have problem with client receiving msg. When I press "send" button Server side ( c++ ) is receiving right equation but when server is sending response client can't accept it somehow... :/

Codes :

Server - Side (c++) :
// Title : Calculator - Server side
// Author/Programmer :
// Date : 14.05.2012
// Version : 0.01
#include "stdafx.h"
#pragma comment(lib, "Ws2_32.lib")
int StartServerListening(unsigned short port);
void EndServer(int socket);

int _tmain(int argc, _TCHAR* argv[])
{
  int serverSocket;
  
	serverSocket = StartServerListening(7700); // Calls our function StartServerListen(); and passes the port 7700
	if (serverSocket == -1)
	{
		cout << "Server: Couldn't sart server Listening\n";
		return 1;
	}
	int clientSocket;
  
	clientSocket = accept(serverSocket, 0, 0); // Accept The Client
  
	if (clientSocket == SOCKET_ERROR)
	{
		cout << "Server: Socket Error\n";
	}
	int nBytes;
	#define MESSAGE_SIZE 256 // This lets us know how much data we will be sending and recieving
	while (true) {
  char inMessage[MESSAGE_SIZE]; // The actual buffer
  char outMessage[MESSAGE_SIZE]; // Our message to send
  nBytes = recv(clientSocket, inMessage, sizeof(inMessage), 0); // Receive at MAX sizeof(inMessage) bytes into inMessage from the client using clientSocket

  
  if (nBytes == SOCKET_ERROR) {
   cout << "Server: Reciving socket error\n";
  }
  printf("Server: Recived Equation : %s\n", inMessage,"\n");
  Calc c(inMessage);
  strcpy(outMessage,c.out_msg);
  cout<<endl <<"Sending Result :"<<outMessage<<endl;

  nBytes = send(clientSocket, outMessage, sizeof(outMessage), 0); // Send sizeof(outMessage) bytes from the buffer "outMessage" to the client on clientSocket.

  if (nBytes == SOCKET_ERROR)
  {
   cout << "Sever: My message was lost and was not sent.\n";
  }
  else
  {
   printf("Server: Result sent : %s\n", outMessage);
  }

}
	// And congratulations ... we have just sent and received data between 2 programs!
	closesocket(clientSocket);
	EndServer(serverSocket); // Shut down the network

system("PAUSE");  
	return 0;
}
// [======================================]
// Functions
// [======================================]
// StartServerListen() - a function to startup winsock, and then open a socket for listening
int StartServerListening(unsigned short port)
{
	WSAData wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR)
	{
		cout << "Server: Could Not Start Up Winsock!\n";
		return -1;
	}
	int mySocket = socket(AF_INET, SOCK_STREAM, 0);
	if (mySocket == SOCKET_ERROR)
	{
		cout << "Server: Socket is stuck again, wont open...\n";
		return -1;
	}
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr.s_addr = INADDR_ANY;
	if (bind(mySocket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
	{
		cout << "Server: Cant Bind the Socket\n";
		closesocket(mySocket);
		return -1;
	}
	if (listen(mySocket, 5) == SOCKET_ERROR)
	{
		cout << "ServeR: Im deaf! No listening socket open!\n";
		closesocket(mySocket);
		return -1;
	}
	cout << "Server: Up and Running Partner!\n";
	return mySocket;
}

// EndServer() - a function to shutdown a socket and clean up winsock
void EndServer(int socket)
{
	// Close our socket
	closesocket(socket);
	// Shut down winsock
	WSACleanup();
	cout << "Server: Server Shutting down\n";
}



Client side (c#) - Send Btn :
private void btnSend_Click(object sender, EventArgs e)
		{
			TcpClient SocketForServer;
			try
			{
				SocketForServer = new TcpClient("localhost", 7700);
			}
			catch
			{
				string err = "Failed to connect to server at {0}:999" + " localhost";
				txtResult.Text = err;
				return;
			}
			NetworkStream networkStream = SocketForServer.GetStream();
			System.IO.StreamWriter streamWriter = new System.IO.StreamWriter(networkStream);
			System.IO.StreamReader streamReader = new System.IO.StreamReader(networkStream);
			string text = eq;
			string res;
			char[] ch_msg;
			ch_msg = new char[256];
			for (int i = 0; i < text.Length; i++)
				ch_msg[i] = text[i];
			streamWriter.WriteLine(ch_msg);
			streamWriter.Flush();
			streamWriter.Close();
			res = streamReader.ReadLine().ToString();
			streamReader.Close();
		  
		  
		  
		}

I think problem my problem is caused because I'm sending ( trying ) char * when c#(client side) ReadLine() reads string... I dont know how to omit it :/

Error I get on client side :
Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.

  • 0
Remebre about KISS & DRY

#5 kernelcoder

kernelcoder

    CC Devotee

  • Expert Member
  • PipPipPipPipPipPip
  • 990 posts
  • Location:Dhaka
  • Programming Language:C, Java, C++, C#, Visual Basic .NET
  • Learning:Objective-C, PHP, Python, Delphi/Object Pascal

Posted 13 June 2012 - 07:26 PM

Note that, the streamWriter & streamReader both points to same socket stream -- networkStream. So if you close any of those two, other one will not be able to access the stream. That's why you are getting the 'Can not access a disposed object - System.Net.Sockets.NetworkStream'. So you just need to omit the line 'streamWriter.Close();' after the line 'streamWriter.Flush();'
  • 0

#6 notes

notes

    CC Resident

  • Advanced Member
  • PipPipPipPip
  • 88 posts
  • Location:Poland
  • Programming Language:C++
  • Learning:Java, C#

Posted 14 June 2012 - 01:51 AM

Thank you,
I solved that problem and got A- from asigment '-' cause I didnt use forking on server side.
  • 0
Remebre about KISS & DRY





Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download