Created
October 8, 2012 23:18
-
-
Save petermoz/3855587 to your computer and use it in GitHub Desktop.
MTRX1702 Assignment 1 Solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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