//----------------------------------------------------------------------------- // File: HelloMath.cpp // Class: None // Parent: None // Children: None // Purpose: Reads matrix from file, adds matrix to itself, and writes result to file. // Author: Melanie Fox // Date: 4/13/07 //----------------------------------------------------------------------------- // The following are standard C/C++ header files. // If a filename is enclosed inside < > it means the header file is in the Include directory. // If a filename is enclosed inside " " it means the header file is in the current directory. #include // Character Types #include // Mathematical Constants #include // Variable Argument Lists #include // Standard Input/Output Functions #include // Utility Functions #include // String Operations #include // Signals (Contol-C + Unix System Calls) #include // Nonlocal Goto (For Control-C) #include // Time and Date information #include // Verify Program Assertion #include // Error Codes (Used in Unix system()) #include // Floating Point Constants #include // Implementation Constants #include // Standard Definitions #include // Exception handling (e.g., try, catch throw) //----------------------------------------------------------------------------- #define PI 3.14159265358979 #define INPUT_ANGLE_ARRAY_SIZE 100 #define PRECISION_ARRAY_SIZE 20 #define LOWER_INPUT_ANGLE_LIMIT 180 #define UPPER_INPUT_ANGLE_LIMIT 720 #define DEFAULT_PRECISION_VALUE 5 #define DEFAULT_ANGLE_VALUE 360 #define LOWER_PRECISION_LIMIT 1 #define UPPER_PRECISION_LIMIT 17 #define SIZE_OF_M 35 #define INPUT_FILENAME "HelloMath3In.txt" #define OUTPUT_FILENAME "HelloMath3Out.txt" #define SIZE_OF_INPUT_STRING 5 #define NUM_OF_COLUMNS 7 #define NUM_OF_ROWS 5 #define PRECISION 5 //----------------------------------------------------------------------------- // Prototypes for local functions (functions not called by code in other files) //----------------------------------------------------------------------------- bool GetStringFromFile( char inputString[], unsigned long sizeOfString, FILE *fptr ) {return( fgets( inputString, sizeOfString, fptr ) );} bool GetStringFromKeyboard( char inputString[], unsigned long sizeOfString ) {return( GetStringFromFile( inputString, sizeOfString, stdin ) );} bool WriteStringToFile( const char outputString[], FILE *fptr ) {return( fprintf( fptr, "%s\n", outputString ) );} bool WriteStringToScreen( const char outputString[] ) {return( WriteStringToFile( outputString, stdout ) );} bool WriteDoubleToFileWithEExponentInSpecifiedPrecision( double x, int precision, FILE *fptr ); bool GetDoubleRowElementsFromFile( double *array, unsigned int numberOfCols, FILE *fptr ); bool GetDoubleMatrixElementsFromFile( double *array, unsigned int numberOfRows, unsigned int numberOfCols, FILE *fptr ); bool WriteDoubleRowElementsToFile( const double *array, unsigned int numberOfCols, int precision, FILE *fptr ); bool WriteDoubleMatrixElementsToFile( const double *array, unsigned int numberOfRows, unsigned int numberOfCols, int precision, FILE *fptr ); const char* ConvertStringToDouble( const char *s, double &returnValue, double defaultValue ); const char* ConvertStringToLong( const char *s, long &returnValue, long defaultValue ); double ConvertFromRadiansToDegrees( double angleInRadians ) {return( angleInRadians*180.0/PI );} double ConvertFromDegreesToRadians( double angleInDegrees ) {return( angleInDegrees*PI/180.0 );} FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ); void AddMatrices( const double *arrayA, const double *arrayB, double *arraySum, unsigned int numberOfElements ); //----------------------------------------------------------------------------- int main( void ) { //Open file containing input matrix const char inputFile[50] = INPUT_FILENAME; const char fileAttributeIn[2] = "r"; FILE* pointerToFile = FileOpenWithMessageIfCannotOpen( inputFile, fileAttributeIn ); if( pointerToFile == NULL ) return 1; //Read input matrix from file double M[NUM_OF_ROWS*NUM_OF_COLUMNS]; double *ptrToM = M; GetDoubleMatrixElementsFromFile( ptrToM, NUM_OF_ROWS, NUM_OF_COLUMNS, pointerToFile ); //Close file containing input matrix fclose( pointerToFile ); //Print array and pause for function debugging purposes for( int i = 1; i<=35; i++ ) printf( "Array entry is %f\n", M[i - 1] ); getchar(); //Add matrices double arraySum[NUM_OF_ROWS*NUM_OF_COLUMNS]; double *ptrToArraySum = arraySum; AddMatrices( ptrToM, ptrToM, ptrToArraySum, NUM_OF_ROWS*NUM_OF_COLUMNS ); //Open output file const char outputFile[50] = OUTPUT_FILENAME; const char fileAttributeOut[2] = "w"; pointerToFile = FileOpenWithMessageIfCannotOpen( outputFile, fileAttributeOut ); if( pointerToFile == NULL ) return 1; //Write result of matrix addition to output file WriteDoubleMatrixElementsToFile( ptrToArraySum, NUM_OF_ROWS, NUM_OF_COLUMNS, PRECISION, pointerToFile ); //Close output file fclose(pointerToFile); // A normal program exit returns 0 (other return values usually signal an error) return 0; } //----------------------------------------------------------------------------- bool WriteDoubleToFileWithEExponentInSpecifiedPrecision( double x, int precision, FILE *fptr ) { // Ensure the precision (number of digits in the mantissa after the decimal point) makes sense. // Next, calculate the field width so it includes one extra space to the right of the number. if( precision < 0 || precision > 17 ) precision = 15; int fieldWidth = precision + 8; // Create the format specifier and print the number char format[20]; sprintf( format, " %%- %d.%dE", fieldWidth, precision ); return fprintf( fptr, format, x ) > 0; } //----------------------------------------------------------------------------- const char* ConvertStringToDouble( const char *s, double &returnValue, double defaultValue ) { // Default return value (in case the string is not a valid number) returnValue = defaultValue; // Check if s is a NULL string or "&^%$#" or "abc" or "123huh" if( s ) { // Use the standard math function strtod to parse the number char *pointerToCharacterAfterNumber = NULL; double x = strtod( s, &pointerToCharacterAfterNumber ); // Ensure the character after the number is a space or '\0', not 'a' or 'z' or ... char characterAfterNumber = pointerToCharacterAfterNumber ? *pointerToCharacterAfterNumber : 'z'; if( characterAfterNumber == '\0' || isspace(characterAfterNumber) ) { returnValue = x; return pointerToCharacterAfterNumber; } } return NULL; } //----------------------------------------------------------------------------- const char* ConvertStringToLong( const char *s, long &returnValue, long defaultValue ) { // Default return value (in case the string is not a valid number) returnValue = defaultValue; // Check if s is a NULL string or "&^%$#" or "abc" or "123huh" if( s ) { // Use the standard math function strtod to parse the number char *pointerToCharacterAfterNumber = NULL; double x = strtol( s, &pointerToCharacterAfterNumber, 10 ); // Ensure the character after the number is a space or '\0', not 'a' or 'z' or ... char characterAfterNumber = pointerToCharacterAfterNumber ? *pointerToCharacterAfterNumber : 'z'; if( characterAfterNumber == '\0' || isspace(characterAfterNumber) ) { returnValue = x; return pointerToCharacterAfterNumber; } } return NULL; } //----------------------------------------------------------------------------- FILE* FileOpenWithMessageIfCannotOpen( const char *filename, const char *attribute ) { FILE *pointerToFile = fopen( filename, attribute ); //Display error message and return null pointer to main if file cannot be opened if( pointerToFile == NULL) { WriteStringToScreen( "File could not be opened." ); getchar(); return 0; } return pointerToFile; } //----------------------------------------------------------------------------- bool GetDoubleRowElementsFromFile( double *array, unsigned int numberOfCols, FILE *fptr ) { double inputValue = 0.0; //Use scanf to parse each entry in a row up to the number of columns for( int j = 1; j <= numberOfCols; j++ ) { fscanf( fptr, "%lf", &inputValue ); array[j-1] = inputValue; } return 0; } //----------------------------------------------------------------------------- bool GetDoubleMatrixElementsFromFile( double *array, unsigned int numberOfRows, unsigned int numberOfCols, FILE *fptr ) { double Row[NUM_OF_COLUMNS]; for( int i = 1; i <= numberOfRows; i++ ) { static int arrayIndex = 1; GetDoubleRowElementsFromFile( Row, numberOfCols, fptr ); for( int j = 1; j <= numberOfCols; j++ ) { array[arrayIndex + j - 2] = Row[j - 1]; } arrayIndex += numberOfCols; } return 0; } //----------------------------------------------------------------------------- bool WriteDoubleRowElementsToFile( const double *array, unsigned int numberOfCols, int precision, FILE *fptr ) { static int rowNumber = 1; for( int i = 1; i <= numberOfCols; i++ ) { WriteDoubleToFileWithEExponentInSpecifiedPrecision( array[rowNumber + i - 2], precision, fptr ); } rowNumber += numberOfCols; return 0; } //----------------------------------------------------------------------------- bool WriteDoubleMatrixElementsToFile( const double *array, unsigned int numberOfRows, unsigned int numberOfCols, int precision, FILE *fptr ) { //For each row, write the row then write a carriage return for( int i = 1; i <= numberOfRows; i++ ) { WriteDoubleRowElementsToFile( array, numberOfCols, precision, fptr ); WriteStringToFile( "\r", fptr ); } return 0; } //----------------------------------------------------------------------------- void AddMatrices( const double *arrayA, const double *arrayB, double *arraySum, unsigned int numberOfElements ) { for( int i = 1; i <= numberOfElements; i++ ) arraySum[i-1] = arrayA[i-1] + arrayB[i-1]; }