Given:
main.c
Code:
/**************************************/
/* main.c */
/* DO NOT MODIFY THIS FILE */
/**************************************/
#include "tests.h"
#include "complex.h"
int main()
{
FILE *errF = NULL;
FILE *reportF = NULL;
char errBuffer[2000] = {0};
printf("\nWelcome to the Complex Number Module Test Program\n\n");
printf("Tests results can be found in file testResults\n");
printf("and error reports in file errorFile\n\n");
if ((errF = fopen("errorFile","w")) == NULL) {
printf("Unable to open errorFile for writing\n");
exit(1);
}
if ((reportF = fopen("testResults","w")) == NULL) {
printf("Unable to open testResults for writing\n");
exit(1);
}
fprintf(reportF,"\n\t\tComplex Number Test Report\n\n");
fprintf(reportF,"output_complex: %s\n",test_output(errBuffer)? "pass" : "fail");
fprintf(reportF,"add_complex: %s\n",test_add(errBuffer)? "pass" : "fail");
fprintf(reportF,"subtract_complex: %s\n",test_subtract(errBuffer)? "pass" : "fail");
fprintf(reportF,"multiply_complex: %s\n",test_multiply(errBuffer)? "pass" : "fail");
fprintf(reportF,"divide_complex: %s\n",test_divide(errBuffer)? "pass" : "fail");
fclose(reportF);
fprintf(errF,"%s",errBuffer);
printf("Normal termination\n\n");
return 0;
}
complex.c:
Code:
#include "complex.h"
const complex ZERO = {0.0,0.0};
/***************************************/
/* ALREADY IMPLEMENTED FUNCTIONS */
/***************************************/
/* utility function */
int good(double im, char op, char ch)
{
if (ch != 'i')
return 0;
if (op != '+' && op != '-')
return 0;
if (im < 0)
return 0;
return 1;
}
complex input_complex(FILE *infile)
{
complex z = {0,0};
double re = 0, im = 0;
char op, ch;
fscanf(infile,"%lf %c%lf%c",&re,&op,&im,&ch);
if (infile != stdin && !good(im,op,ch)) {
printf("Improperly formed complex number in input file; goodbye\n");
exit(1);
}
while(!good(im,op,ch)) {
printf("Illegal input for complex number; try again\n");
fscanf(infile,"%lf %c%lf%c",&re,&op,&im,&ch);
}
z.re = re;
if (op == '+')
z.im = im;
else
z.im = -im;
return z;
}
int equal_complex(complex z, complex w)
{
return z.re == w.re && z.im == w.im;
}
double mag_squared(complex z)
{
return z.re*z.re + z.im*z.im;
}
complex scalar_multiple(double c, complex z)
{
complex w = ZERO;
w.re = c*z.re;
w.im = c*z.im;;
return w;
}
complex conjugate(complex z)
{
complex w = ZERO;
w.re = z.re;
w.im = -z.im;
return w;
}
/*****************************************************************/
/* FUNCTIONS FOR YOU TO IMPLEMENT - JUST STUBS FOR NOW */
/*****************************************************************/
/* Output Function Errors:
expected: 1 + 2i
actual: 0 + 1072693248i
expected: 1 + 2i
actual: 0 + 1072693248i*/
void output_complex(FILE *outf,complex z)
{
if(z.im == 0)
{
fprintf(outf,"%lf", z.re);
}
if(z.re == 0)
{
if(z.im == 1)
{
fprintf(outf,"i");
}
fprintf(outf,"%lfi", z.im);
}
if(z.im == 1)
{
fprintf(outf,"%lf + i", z.re);
}
if(z.im < 0)
{
if(z.im == -1)
{
z.im *= -1;
fprintf(outf,"%lf - i", z.re);
}
z.im *= -1;
fprintf(outf,"%lf - %lfi", z.re, z.im);
}
fprintf(outf,"%lf + %lfi", z.re, z.im);
}
complex.h
Code:
/***************************/
/* file complex.h */
/***************************/
#include <stdio.h>
#include <stdlib.h>
#ifndef _COMPLEX_H_
#define _COMPLEX_H_
typedef struct {
double re;
double im;
} complex;
/***********************************************************************/
/* You do not need to implement or test the next two functions */
/* Their implementations are already in complex.c and have been tested */
/***********************************************************************/
/* reads in a complex number from input and returns that value */
complex input_complex(FILE *infile);
/* returns 1 if z = w and 0 otherwise */
int equal_complex(complex z, complex w);
/*****************************************************************/
/* The remaining functions are for you to implement in complex.c */
/*****************************************************************/
/* print z to file outf in the correct format */
/* you may assume outf has been opened for writing */
void output_complex(FILE *outf,complex z);
/* compute and return the square of |z| */
/* DO NOT USE SQUARE ROOT; NOT NEEDED! */
double mag_squared(complex z);
/* compute and return cz */
complex scalar_multiple(double c, complex z);
/* compute and return the conjugate of z */
complex conjugate(complex z);
/* compute and return z+w */
complex add_complex(complex z, complex w);
/* compute and return z-w */
complex subtract_complex(complex z, complex w);
/* compute and return z*w */
complex multiply_complex(complex z, complex w);
/* compute and return z/w */
complex divide_complex(complex z, complex w);
#endif
tests.c
Code:
/**************************************/
/* tests.c */
/* DO NOT MODIFY THIS FILE */
/**************************************/
#include "tests.h"
#include "complex.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static const complex ZERO = {0.0,0.0};
int test_output(char * err_messages)
{
complex test_entries[OUTPUT_COUNT] = OUTPUT_DATA;
const char * correctStrings[OUTPUT_COUNT] = OUTPUT_CORRECT;
int i = 0, errors = 0;
char buffer[30] = {0};
char temp[50] = {0};
FILE * outputF = fopen("complex.out","w");
if (outputF == NULL) {
printf("Unable to open complex.out for outputting complex numbers\n");
return 0;
}
for(i = 0; i < OUTPUT_COUNT; i++) {
output_complex(outputF,test_entries[i]);
fprintf(outputF,"\n");
}
fclose(outputF);
if ((outputF = fopen("complex.out","r")) == NULL) {
printf("Unable to reopen complex.out for reading\n");
return 0;
}
for(i = 0; i < OUTPUT_COUNT; i++) {
fgets(buffer,30,outputF);
buffer[strlen(buffer)-1] = 0;
if (strcmp(buffer,correctStrings[i]) != 0) {
if (!errors) {
sprintf(err_messages,"%s\n\nOutput Function Errors:\n",err_messages);
errors = 1;
}
sprintf(err_messages,"%sexpected: %s\nactual: %s\n",err_messages,
correctStrings[i],buffer);
}
}
fclose(outputF);
unlink("complex.out");
return !errors;
}
int test_add(char * err_messages)
{
complex left_args[ADD_COUNT] = ADD_LEFT_ARGS;
complex right_args[ADD_COUNT] = ADD_RIGHT_ARGS;
complex corrects[ADD_COUNT] = ADD_CORRECT;
complex computed[ADD_COUNT] = {ZERO};
complex left = ZERO, right = ZERO, correct = ZERO, result = ZERO;
int i = 0, errors = 0;
for(i = 0; i < ADD_COUNT; i++) {
left = left_args[i];
right = right_args[i];
correct = corrects[i];
result = add_complex(left,right);
if (!equal_complex(result,correct)) {
if (!errors) {
strcat(err_messages,"\n\nAdd Errors:\n");
errors = 1;
}
sprintf(err_messages,"%s(%.2f,%.2f)+(%.2f,%.2f)\nreceived (%.2f,%.2f), correct (%.2f,%.2f)\n\n",
err_messages,left.re,left.im,right.re,right.im,result.re,result.im,
correct.re,correct.im);
}
}
return !errors;
}
tests.h
Code:
#ifndef _TESTS_H_
#define _TESTS_H_
#define OUTPUT_COUNT 2
#define OUTPUT_DATA {{1,2},{1,2}}
#define OUTPUT_CORRECT {"1 + 2i","1 + 2i"}
#define ADD_COUNT 2
#define ADD_LEFT_ARGS {{2,3},{2,3} }
#define ADD_RIGHT_ARGS {{1,2},{1,2}}
#define ADD_CORRECT {{3,5},{3,5}}
#define SUBTRACT_COUNT 2
#define SUBTRACT_LEFT_ARGS {{2,3},{2,3} }
#define SUBTRACT_RIGHT_ARGS {{1,2},{1,2}}
#define SUBTRACT_CORRECT {{1,1},{1,1}}
#define MULTIPLY_COUNT 2
#define MULTIPLY_LEFT_ARGS {{2,3},{2,3} }
#define MULTIPLY_RIGHT_ARGS {{1,2},{1,2}}
#define MULTIPLY_CORRECT {{-4,7},{-4,7}}
#define DIVIDE_COUNT 2
#define DIVIDE_LEFT_ARGS {{2,3},{2,3} }
#define DIVIDE_RIGHT_ARGS {{1,2},{1,2}}
#define DIVIDE_CORRECT {{1.6,0.2},{1.6,0.2}}
/*******************************************/
/* DO NOT MODIFY THE PROTOTYPES BELOW */
/*******************************************/
int test_output(char *err_messages);
int test_add(char *err_messages);
int test_subtract(char *err_messages);
int test_multiply(char *err_messages);
int test_divide(char *err_messages);
#endif