Skip to content

Instantly share code, notes, and snippets.

@petermoz
Created October 8, 2012 23:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save petermoz/3855587 to your computer and use it in GitHub Desktop.
Save petermoz/3855587 to your computer and use it in GitHub Desktop.
MTRX1702 Assignment 1 Solution
/*
* MTRX1702 Assignment 1
* Peter Morton, 2012
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define PI 3.14159265358979323846
#define BUF_SIZE 128
typedef enum
{
ERR = 1,
DEG = 2,
RAD = 4,
SIN = 8,
COS = 16,
TAN = 32
} cmd_flags;
void usage(void);
int run_string(char* buf);
unsigned int cmd_to_flags(char *cmd);
void display_table(unsigned int flags, float start, float final, int n_int);
void print_flags(cmd_flags flags);
int main(int argc, char* argv[])
{
char buf[BUF_SIZE];
printf("TRIG: the trigonometric calculator\n");
if(argc > 1)
{
int i;
buf[0] = '\0';
for(i = 1; i < argc; i++)
{
strcat(buf, argv[i]);
strcat(buf, " ");
}
run_string(buf);
return 0;
}
do
{
printf("\nPlease input request (h-help, q-quit): ");
fgets(buf, BUF_SIZE, stdin);
} while(run_string(buf));
return 0;
}
void usage(void)
{
printf("The input format is a single line of letters and numbers comprising\n"
"the following fields: \n\n"
"\t<types> <start-value> <final-value> <intermediate-rows>\n\n"
"These fields must be input in the order shown above, where <types>\n"
"is a set of letters, and the others are single numbers defining\n"
"the range of computation. The <types> field consists of zero or more\n"
"of the letters from the set <stcdr>, which indicate respectively,\n\n"
"\t(1) The desired trig functions: sin, tan, cos.\n"
"\t(2) Whether to use degrees or radians for input parameters.\n\n"
"Example input: scr 0 2.3 3\n");
}
/* Run the command, return TRUE if should continue */
int run_string(char* buf)
{
char cmd[BUF_SIZE];
char rem[BUF_SIZE]; /* Remaining (non-parsed) input */
float start, final;
int n_int;
unsigned int flags = 0;
/* Scan for input in decreasing order of likeliness to fail */
if(sscanf(buf, "%s %f %f %d%s", cmd, &start, &final, &n_int, rem) == 4)
{
if(n_int < 0)
flags |= ERR;
else
flags = cmd_to_flags(cmd);
}
else if(sscanf(buf, "%f %f %d%s", &start, &final, &n_int, rem) == 3)
{
if(n_int < 0)
flags |= ERR;
else
flags = cmd_to_flags("");
}
else if(sscanf(buf, "%s %s", cmd, rem) == 1)
{
if(strcmp(cmd, "q") == 0)
{
return 0;
}
else if(strcmp(cmd, "h") == 0)
{
usage();
return 1;
}
flags |= ERR;
}
else
{
flags |= ERR;
}
/*print_flags(flags);*/
if(flags & ERR)
{
printf("Error: Illegal input!\n");
}
else
{
display_table(flags, start, final, n_int);
}
return 1;
}
/* Convert command string into flags, set ERR flag if problem */
unsigned int cmd_to_flags(char *cmd)
{
unsigned int flags = 0;
char *s = cmd;
for(; *s != '\0'; s++)
{
switch(tolower(*s))
{
case 's':
flags |= SIN;
break;
case 'c':
flags |= COS;
break;
case 't':
flags |= TAN;
break;
case 'r':
flags |= RAD;
break;
case 'd':
flags |= DEG;
break;
default:
flags |= ERR;
}
}
/* Check for case that no output column was requested
* in which case we default to all */
if((flags & (SIN | COS | TAN)) == 0)
{
flags |= (SIN | COS | TAN);
}
/* Check that user didn't specify rad and deg
* If specified neither, force DEG by default */
if((flags & RAD) && (flags & DEG))
{
flags |= ERR;
}
else if(!(flags & RAD))
{
flags |= DEG;
}
return flags;
}
void display_table(unsigned int flags, float start, float final, int n_int)
{
char line[BUF_SIZE];
char *p;
int i;
float val;
float incr;
/* Convert limits to radians */
if(flags & DEG)
{
start = start * PI / 180.0f;
final = final * PI / 180.0f;
}
/* Print header */
p = line;
p += sprintf(p, "Degrees,Radians,");
if(flags & SIN)
p += sprintf(p, "Sin,");
if(flags & COS)
p += sprintf(p, "Cos,");
if(flags & TAN)
p += sprintf(p, "Tan,");
*(p - 1) = '\0'; /* Remove trailing "," */
printf("%s\n", line);
incr = (final - start) / (n_int + 1);
for(i = 0; i < n_int + 2; i++)
{
val = start + incr * i;
p = line;
p += sprintf(p, "%0.3f,%0.3f,", val * 180.0 / PI, val);
if(flags & SIN)
p += sprintf(p, "%0.3f,", sin(val));
if(flags & COS)
p += sprintf(p, "%0.3f,", cos(val));
if(flags & TAN)
p += sprintf(p, "%0.3f,", tan(val));
*(p - 1) = '\0'; /* Remove trailing "," */
printf("%s\n", line);
}
}
void print_flags(unsigned int flags)
{
int i;
printf("Flags: ");
for(i = 0; i < 6; i++)
{
printf("%d", (flags & (1 << i)) > 0);
}
printf("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment