Visual C++ 2012入门经典(第6版) 课后练习(第06章)

本文介绍了一个简单的命令行计算器程序的设计与实现。该程序能够解析并计算基本的数学表达式,包括加减乘除运算及括号内的计算。文章还讨论了如何处理表达式中的错误,并通过几个示例展示了程序的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、

1.main.cpp

#include <iostream>

using namespace std;

int ascVal(size_t i, const char* p);

int main()
{
	char* words = "Hello world!";

	//int (*pFunc)(size_t i, const char* p) = ascVal;
	auto pFunc = ascVal;

	cout << static_cast<char>(pFunc(7,words));

	return 0;
}

int ascVal(size_t i, const char* p)
{
	//Return the ASCII value of the char
	if(!p || i > strlen(p))
		return -1;
	else
		return p[i];
}


二、

1.main.cpp

#include <iostream>

using namespace std;

template<class T> 
int equal(T v1, T v2)
{
	if(v1 == v2)
		return 1;
	else
		return 0;
}

int equal(char* v1, char* v2);

int main()
{
	//char
	char c1('a'), c2('b');
	if(equal(c1, c2) == 1)
		cout << c1 << " == " << c2 << endl;
	else
		cout << c1 << " != " << c2 << endl << endl;

	//int
	int n1(23), n2(42);
	if(equal(n1, n2) == 1)
		cout << n1 << " == " << n2 << endl << endl;
	else
		cout << n1 << " != " << n2 << endl << endl;

	//double
	double d1(23.4), d2(23.4);
	if(equal(d1, d2) == 1)
		cout << n1 << " == " << n2 << endl << endl;
	else
		cout << n1 << " != " << n2 << endl << endl;

	//char*
	char* pc1("tzb");
	char* pc2("tzb");
	if(equal(pc1, pc2) == 1)
		cout << pc1 << " == " << pc2 << endl << endl;
	else
		cout << pc1 << " != " << pc2 << endl << endl;

	return 0;
}

//特例化的equal函数
int equal(char* v1, char* v2)
{
	cout << "This is special func of char*:" << endl;

	if(strcmp(v1, v2) == 0)
		return 1;
	else
		return 0;
}

三、

1.main.cpp

#include <cctype>
#include <iostream>
#include <cstdlib>
#include <iomanip>

using namespace std;

void eatspaces(char* str);
double expr(char* str);
double term(char* str,int& index);
double number(char* str,int& index);
char* extract(char* str,int& index);

int main()
{
	const int MAX(80);
	char buffer[MAX] = {0};

	cout << endl
		 << "welcome to your friendly calculator."
		 << endl
		 << "Enter an expression, or an empty line to quit."
		 << endl;

	while(true)
	{
		cin.getline(buffer,sizeof(buffer));
		eatspaces(buffer);

		if(!buffer[0])
			return 0;

		try
		{
			cout << "\t = " << expr(buffer)
				 << endl << endl;
		}
		catch(const char* pEx)
		{
			cerr << pEx << endl;
			cerr << "Ending program." << endl;
			return 1;
		}
		catch(int nPos)
		{
			if(-1 == nPos)
				cerr << setw(strnlen_s(buffer, 80) + 1) << "^";
			else
				cerr << setw(nPos + 1) << "^";
			return 1;
		}
	}

	return 0;
}

//Function to eliminate spaces from a string
void eatspaces(char* str)
{
	int i(0),j(0);

	while((*(str + i) = *(str + j++)) != '\0')
		if(*(str + i) != ' ')
			i++;

	return;
}

//Function to evaluate an arithmetic expression
double expr(char* str)
{
	double value(0.0);
	int index(0);

	value = term(str,index);

	while(true)
	{
		switch (*(str + index++))
		{
		case '\0':
			return value;
		case '+':
			value += term(str,index);
			break;
		case '-':
			value -= term(str,index);
			break;
		default:
			//char message[38] = "Expression evaluation error. Found: ";
			//strncat_s(message, str + index - 1, 1);	
			//throw message;
			throw index - 1;
			break;
		}
	}
}

//Function to get the value of a term
double term(char* str,int& index)
{
	double value(0.0);

	value = number(str,index);

	while(true)
	{
		if(*(str + index) == '*')
			value *= number(str,++index);
		else if(*(str + index) == '/')
			value /= number(str,++index);
		else
			break;
	}

	return value;
}

//Function to recognize an expression in parentheses
//or a number in a string
double number(char* str,int& index)
{
	double value(0.0);

	if(*(str + index) == '(')
	{
		int nPrePos = index;
		try
		{
			char* psubstr(nullptr);
			psubstr = extract(str, ++index);
			value = expr(psubstr);
			delete[] psubstr;
		}
		catch(int nPos)
		{
			if(-1 == nPos)
				throw -1;							//如果是括号不是成对出现,则返回-1,指向最后一个位置后面,表示搜索最后一个位置后扔未找到匹配的括号
			else
				throw nPos + nPrePos + 1;			//返回在括号表达式中发现错误的位置加上括号开始的位置
		}

		return value;
	}

	if(!isdigit(*(str + index)))
	{
		//char message[31] = "Invalid character in number: ";
		//strncat_s(message, str + index, 1);
		//throw message;
		throw index;
	}

	while(isdigit(*(str + index)))
		value = 10*value + (*(str + index++) - '0');

	if(*(str + index) != '.')
		return value;
	
	double factor(1.0);
	while(isdigit(*(str + (++index))))
	{
		factor *= 0.1;
		value = value + (*(str + index) - '0')*factor;
	}

	return value;
}

//Function to extract a substring between parentheses
char* extract(char* str,int& index)
{
	char* pstr(nullptr);		//Pointer to new string for return
	int numL(0);				//count of left parentheses found
	int bufindex(index);		//Save starting value for index

	do
	{
		switch (*(str + index))
		{
		case ')':
			if(0 == numL)
			{
				++index;
				pstr = new char[index - bufindex];
				if(!pstr)
				{
					throw "Memory allocation failed.";
				}
				strncpy_s(pstr, index - bufindex, str + bufindex, index - bufindex - 1);

				return pstr;
			}
			else
				numL--;
			break;
		case '(':
			numL++;
			break;
		default:
			break;
		}
	}
	while (*(str + index++) != '\0');

	//throw "Ran off the end of the expression, must be bad input.";
	throw -1;		//如果是括号不是成对出现,则返回-1,指向最后一个位置后面,表示搜索最后一个位置后扔未找到匹配的括号
}

四、

1.main.cpp

#include <cctype>
#include <iostream>
#include <cstdlib>

using namespace std;

void eatspaces(char* str);
double expr(char* str);
double term(char* str,int& index);
double number(char* str,int& index);
char* extract(char* str,int& index);
int IsInterger(double dValue);

int main()
{
	const int MAX(80);
	char buffer[MAX] = {0};

	cout << endl
		 << "welcome to your friendly calculator."
		 << endl
		 << "Enter an expression, or an empty line to quit."
		 << endl;

	while(true)
	{
		cin.getline(buffer,sizeof(buffer));
		eatspaces(buffer);

		if(!buffer[0])
			return 0;

		try
		{
			cout << "\t = " << expr(buffer)
				 << endl << endl;
		}
		catch(const char* pEx)
		{
			cerr << pEx << endl;
			cerr << "Ending program." << endl;
			return 1;
		}
	}

	return 0;
}

//Function to eliminate spaces from a string
void eatspaces(char* str)
{
	int i(0),j(0);

	while((*(str + i) = *(str + j++)) != '\0')
		if(*(str + i) != ' ')
			i++;

	return;
}

//Function to evaluate an arithmetic expression
double expr(char* str)
{
	double value(0.0);
	int index(0);

	value = term(str,index);

	while(true)
	{
		switch (*(str + index++))
		{
		case '\0':
			return value;
		case '+':
			value += term(str,index);
			break;
		case '-':
			value -= term(str,index);
			break;
		default:
			char message[38] = "Expression evaluation error. Found: ";
			strncat_s(message, str + index - 1, 1);
			throw message;
			break;
		}
	}
}

//Function to get the value of a term
double term(char* str,int& index)
{
	double value(0.0);

	value = number(str,index);

	while(true)
	{
		if(*(str + index) == '*')
			value *= number(str,++index);
		else if(*(str + index) == '/')
			value /= number(str,++index);
		else if(*(str + index) == '^')
		{
			int nTemp = IsInterger(number(str,++index));
			double dTempValue = value;
			for(int i = 1; i < nTemp; i++)
				value *= dTempValue;
		}
		else
			break;
	}

	return value;
}

//Function to recognize an expression in parentheses
//or a number in a string
double number(char* str,int& index)
{
	double value(0.0);

	if(*(str + index) == '(')
	{
		char* psubstr(nullptr);
		psubstr = extract(str, ++index);
		value = expr(psubstr);
		delete[] psubstr;

		return value;
	}

	if(!isdigit(*(str + index)))
	{
		char message[31] = "Invalid character in number: ";
		strncat_s(message, str + index, 1);
		throw message;
	}

	while(isdigit(*(str + index)))
		value = 10*value + (*(str + index++) - '0');

	if(*(str + index) != '.')
		return value;
	
	double factor(1.0);
	while(isdigit(*(str + (++index))))
	{
		factor *= 0.1;
		value = value + (*(str + index) - '0')*factor;
	}

	return value;
}

//Function to extract a substring between parentheses
char* extract(char* str,int& index)
{
	char* pstr(nullptr);		//Pointer to new string for return
	int numL(0);				//count of left parentheses found
	int bufindex(index);		//Save starting value for index

	do
	{
		switch (*(str + index))
		{
		case ')':
			if(0 == numL)
			{
				++index;
				pstr = new char[index - bufindex];
				if(!pstr)
				{
					throw "Memory allocation failed.";
				}
				strncpy_s(pstr, index - bufindex, str + bufindex, index - bufindex - 1);

				return pstr;
			}
			else
				numL--;
			break;
		case '(':
			numL++;
			break;
		default:
			break;
		}
	}
	while (*(str + index++) != '\0');

	throw "Ran off the end of the expression, must be bad input.";
}

//如果是整数,则返回整数值;否则抛异常
int IsInterger(double dValue)
{
	if(dValue - static_cast<int>(dValue) > 0)
		throw "The power is not an interger.";
	else
		return static_cast<int>(dValue);
}

五、

1.main.cpp

#include <cctype>
#include <iostream>
#include <cstdlib>

using namespace std;

void eatspaces(char* str);
double expr(char* str);
double term(char* str,int& index);
double number(char* str,int& index);
char* extract(char* str,int& index);

int main()
{
	const int MAX(80);
	char buffer[MAX] = {0};

	cout << endl
		 << "welcome to your friendly calculator."
		 << endl
		 << "Enter an expression, or an empty line to quit."
		 << endl;

	while(true)
	{
		cin.getline(buffer,sizeof(buffer));
		eatspaces(buffer);

		if(!buffer[0])
			return 0;

		try
		{
			cout << "\t = " << expr(buffer)
				 << endl << endl;
		}
		catch(const char* pEx)
		{
			cerr << pEx << endl;
			cerr << "Ending program." << endl;
			return 1;
		}
	}

	return 0;
}

//Function to eliminate spaces from a string
void eatspaces(char* str)
{
	int i(0),j(0);

	while((*(str + i) = *(str + j++)) != '\0')
		if(*(str + i) != ' ')
			i++;

	return;
}

//Function to evaluate an arithmetic expression
double expr(char* str)
{
	double value(0.0);
	int index(0);

	value = term(str,index);

	while(true)
	{
		switch (*(str + index++))
		{
		case '\0':
			return value;
		case '+':
			value += term(str,index);
			break;
		case '-':
			value -= term(str,index);
			break;
		default:
			char message[38] = "Expression evaluation error. Found: ";
			strncat_s(message, str + index - 1, 1);
			throw message;
			break;
		}
	}
}

//Function to get the value of a term
double term(char* str,int& index)
{
	double value(0.0);

	value = number(str,index);

	while(true)
	{
		if(*(str + index) == '*')
			value *= number(str,++index);
		else if(*(str + index) == '/')
			value /= number(str,++index);
		else
			break;
	}

	return value;
}

//Function to recognize an expression in parentheses
//or a number in a string
double number(char* str,int& index)
{
	double value(0.0);

	if(*(str + index) == '(')
	{
		char* psubstr(nullptr);
		psubstr = extract(str, ++index);
		value = expr(psubstr);
		delete[] psubstr;

		return value;
	}
	//sind()
	else if(*(str + index) == 's' && *(str + index + 1) == 'i' && *(str + index + 2) == 'n' && *(str + index + 3) == 'd' && *(str + index + 4) == '(')
	{
		char* psubstr(nullptr);
		index += 5;
		psubstr = extract(str, index);
		value = expr(psubstr) / 360 * 3.141592653;
		delete[] psubstr;

		return value;
	}

	if(!isdigit(*(str + index)))
	{
		char message[31] = "Invalid character in number: ";
		strncat_s(message, str + index, 1);
		throw message;
	}

	while(isdigit(*(str + index)))
		value = 10*value + (*(str + index++) - '0');

	if(*(str + index) != '.')
		return value;
	
	double factor(1.0);
	while(isdigit(*(str + (++index))))
	{
		factor *= 0.1;
		value = value + (*(str + index) - '0')*factor;
	}

	return value;
}

//Function to extract a substring between parentheses
char* extract(char* str,int& index)
{
	char* pstr(nullptr);		//Pointer to new string for return
	int numL(0);				//count of left parentheses found
	int bufindex(index);		//Save starting value for index

	do
	{
		switch (*(str + index))
		{
		case ')':
			if(0 == numL)
			{
				++index;
				pstr = new char[index - bufindex];
				if(!pstr)
				{
					throw "Memory allocation failed.";
				}
				strncpy_s(pstr, index - bufindex, str + bufindex, index - bufindex - 1);

				return pstr;
			}
			else
				numL--;
			break;
		case '(':
			numL++;
			break;
		default:
			break;
		}
	}
	while (*(str + index++) != '\0');

	throw "Ran off the end of the expression, must be bad input.";
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值