⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soln6_5clr.cpp

📁 Wrox.Ivor.Hortons.Beginning.Visual.C.Plus.Plus.2008 With sourcecode
💻 CPP
字号:
// Ex6_5CLR.cpp : main project file.
// A CLR calculator supporting parentheses

#include "stdafx.h"
#include <cstdlib>                          // For exit()

using namespace System;
String^ eatspaces(String^ str);             // Function to eliminate blanks
double expr(String^ str);                   // Function evaluating an expression
double term(String^ str, int^ index);       // Function analyzing a term
double number(String^ str, int^ index);     // Function to recognize a number
String^ extract(String^ str, int^ index);   // Function to extract a substring
void error(String^ str, int index);         // Function to identify an error
double doOperation(String^ op, double value);   // Execute math function

int main(array<System::String ^> ^args)
{
  String^ buffer;    // Input area for expression to be evaluated
  
  Console::WriteLine(L"Welcome to your friendly calculator.");
  Console::WriteLine(L"Enter an expression, or an empty line to quit.");

  for(;;)
  {
    buffer = eatspaces(Console::ReadLine());         // Read an input line

    if(String::IsNullOrEmpty(buffer))                // Empty line ends calculator
      return 0;

    Console::WriteLine(L"  = {0}\n\n",expr(buffer)); // Output value of expression
  }
  return 0;
}

// Function to eliminate spaces from a string
String^ eatspaces(String^ str)
{
  // Array to hold string without spaces  
  array<wchar_t>^ chars = gcnew array<wchar_t>(str->Length);
  int length = 0;                      // Number of chars in array

  // Copy non-space characters to chars array
  for each(wchar_t ch in str)
    if(ch != ' ')
      chars[length++] = ch;

  // Return chars array as string
  return gcnew String(chars, 0, length);
}

// Function to evaluate an arithmetic expression
double expr(String^ str)
{
  int^ index = 0;                      // Keeps track of current character position

  double value = term(str, index);     // Get first term

  while(*index < str->Length)
  {
    switch(str[*index])                // Choose action based on current character
    {
      case '+':                        // + found so 
         ++(*index);                   // increment index and add
         value += term(str, index);    // the next term
         break;

      case '-':                        // - found so
          ++(*index);                  // decrement index and add
        value -= term(str, index);     // the next term
         break;

      default:                         // If we reach here the string is junk
        Console::WriteLine(L"Arrrgh!*#!! There's an error.\n");
        error(str, *index-1);
        exit(1);
    }
  }
  return value;
}

// Function to get the value of a term
double term(String^ str, int^ index)
{
  double value = number(str, index);        // Get the first number in the term

  // Loop as long as we have characters and a good operator
  while(*index < str->Length)
  {
    if(str[*index] == L'*')                 // If it's multiply,
    {
      ++(*index);                           // increment index and
      value *= number(str, index);          // multiply by next number
    }
    else if( str[*index] == L'/')           // If it's divide
    {
      ++(*index);                           // increment index and
      value /= number(str, index);          // divide by next number
    }
    else if( str[*index] == L'^')                    // If it's exponentiation
    {
      ++(*index);                                    // increment index and
      value = Math::Pow(value, number(str, index));  // power of next number
    }
    else
      break;                                // Exit the loop
 }
  // We've finished, so return what we've got
  return value;                             
}

// Function to recognize a number
double number(String^ str, int^ index)
{
  double value = 0.0;                       // Store for the resulting value

  // Look for a math function name
  String^ op = "";
  while (Char::IsLetter(str,*index))      // Copy the function name
  {
    op += str[*index];
    ++(*index);
  }

  // Check for expression between parentheses
  if(str[*index] == L'(' )                  // Start of parentheses
  {
    ++(*index);
    String^ substr = extract(str, index);   // Extract substring in brackets
    if(op->Length > 0)
      return doOperation(op, expr(substr));
    else
      return expr(substr);                    // Return substring value
  }

  // Loop accumulating leading digits
  while((*index < str->Length) && Char::IsDigit(str, *index))
  {
    value = 10.0*value + Char::GetNumericValue(str[(*index)]);
    ++(*index);
  }

  // Not a digit when we get to here
  if((*index == str->Length) || str[*index] != '.')   // so check for decimal point
    return value;                                     // and if not, return value

  double factor = 1.0;                 // Factor for decimal places
  ++(*index);                          // Move to digit

  // Loop as long as we have digits
  while((*index < str->Length) && Char::IsDigit(str, *index))   
  {
    factor *= 0.1;                     // Decrease factor by factor of 10
    value = value + Char::GetNumericValue(str[*index])*factor; // Add decimal place
    ++(*index);
  }

  return value;                        // On loop exit we are done
}

// Function to extract a substring between parentheses 
String^ extract(String^ str, int^ index)
{
  // Temporary space for substring
  array<wchar_t>^ buffer = gcnew array<wchar_t>(str->Length); 
  String^ substr;                      // Substring to return
  int numL = 0;                        // Count of left parentheses found
  int bufindex = *index;               // Save starting value for index

  while(*index < str->Length)
  {
    buffer[*index - bufindex] = str[*index];
    switch(str[*index])
    {
      case ')':
        if(numL == 0)
        {
          array<wchar_t>^ substrChars = gcnew array<wchar_t>(*index - bufindex);
          str->CopyTo(bufindex, substrChars, 0, substrChars->Length);
          substr = gcnew String(substrChars);
          ++(*index);

          return substr;               // Return substring in new memory
        }
        else
          numL--;                      // Reduce count of '(' to be matched
        break;

      case '(':
        numL++;                        // Increase count of '(' to be 
                                       // matched
        break;
      }
    ++(*index);
  }

  Console::WriteLine(L"Ran off the end of the expression, must be bad input.");
  exit(1);
  return substr;
}

// Function to identify an error
void error(String^ str, int index)
{
   Console::WriteLine(str);
   Console::Write(gcnew String(' ',index));
   Console::WriteLine(" ^");
}

// Execute math function
double doOperation(String^ op, double value)
{
  double degToRad = 180.0/Math::PI;
  if (String::Compare(op, L"sin", true) == 0)
    return Math::Sin(value);
   else if (String::Compare(op, L"sind", true) == 0)
      return Math::Sin(value/degToRad);
   else if (String::Compare(op, L"cos", true) == 0)
      return Math::Cos(value);
   else if (String::Compare(op, L"cosd", true) == 0)
      return Math::Cos(value/degToRad);
   else if (String::Compare(op, L"tan", true) == 0)
     return Math::Tan(value);
   else if (String::Compare(op, L"tand", true) == 0)
      return Math::Tan(value/degToRad);
   else if (String::Compare(op, L"sqrt", true) == 0)
     return Math::Sqrt(value);
   else
   {
     Console::WriteLine(L"Error: unknown operation '" + op + "'");
     exit(1);
   }
   return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -