//-------------------------------------------------------------------------------------------------------------------- // Program implements a vector whose length is arbitrary and whose default elements are 0 unless specifically // set otherwise. //-------------------------------------------------------------------------------------------------------------------- #include // Standard I/O definitions. #include // Definition for resetioflags(...). #include // Definition of 'int atol(...)'. #include // string class and operations. #include // Definition of isspace(char c). #include "classes.h" // Header for vector class using namespace std; //-------------------------------------------------------------------------------------------------------------------- // Removes the next white-space separated token from buffer and returns it in arg. If no such argument exists, arg // is set to "". If buffer is left without any non-white-space characters, it also is set to "". //-------------------------------------------------------------------------------------------------------------------- void ObtainArgument( string &buffer, string &arg ) { int commandstart; // Position of first non-white space character in buffer. int commandend; // Position of last non-white space character in buffer. arg = ""; // Find the first non-white space character. If no such character exists, set commandstart to length of buffer. commandstart = buffer.find_first_not_of( " \t", 0 ); if ( commandstart == -1 ) { commandstart = buffer.length(); } // if // Find the last non-white space character. If no such character exists, set commandstart to length of buffer. commandend = buffer.find( " ", 1 ); if ( commandend == -1 ) { commandend = buffer.find( "\t", 1 ); if ( commandend == -1 ) { commandend = buffer.length(); } // if } // if // If have at least one character, remove the argument from buffer; otherwise, set buffer to "". if ( commandend > commandstart ) { arg = buffer.substr( commandstart, commandend-commandstart ); buffer = buffer.substr( commandend, buffer.length() - commandend ); } else { buffer = ""; } // if } // ObtainArgument //-------------------------------------------------------------------------------------------------------------------- // Returns true if the given string can be considered an integer. Only handles simple integers, no scientific // notation. //-------------------------------------------------------------------------------------------------------------------- bool IsInt( string value ) { bool retvalue = true; for ( int i = 0; i < value.length() && retvalue; i += 1 ) { if ( i == 0 && (value[i] == '-' || value[i] == '+') ) { } else if ( !isdigit( value[i] ) ) { retvalue = false; } // if } // for return retvalue; } // IsInt //-------------------------------------------------------------------------------------------------------------------- // Obtain the command, the vector to which it is to be applied, and any arguments that may apply to the command. //-------------------------------------------------------------------------------------------------------------------- bool ParseCommand( string buffer, char &command, int &vecIndex, int &subscript, int &value ) { string splitBuf[MAXC]; // Buffer for line split into arguments. int int_splitBuf[MAXC]; // Integer version of command arguments. int numSplit; // # of values from string split. int i; // Loop index. bool retValidCommand = true; // Returns true if the command was valid, else returns false. string copy; // Copy of buffer since parsing takes it apart. command = ' '; // Initialize to empty. vecIndex = 0; subscript = 0; value = 0; numSplit = 0; copy = buffer; for ( i = 0; i < MAXC; i += 1 ) { splitBuf[i] = ""; ObtainArgument( copy, splitBuf[i] ); if ( splitBuf[i].length() > 0 ) { numSplit += 1; } // if } // for command = buffer[0]; // Verify that we have a proper command. if ( command == COMMENT ) { // Do nothing. } else if ( (buffer.length() < 2 || !isspace(buffer[1])) && command != FETCH && command != ASSIGN && command != STATUS ) { cerr << "ERROR: unknown command '" << buffer << "' entered." << endl; retValidCommand = false; } else if ( numSplit < 2 || numSplit >= MAXC ) { cerr << "ERROR: invalid number of parameters for '" << buffer << "'." << endl; retValidCommand = false; } else { // Verify that each argument is an integer. for ( i = 1; i < numSplit; i += 1 ) { if ( !IsInt(splitBuf[i]) ) { cerr << "ERROR: invalid integer '" << splitBuf[i] << "' entered for '" << buffer << "'." << endl; retValidCommand = false; break; } else { int_splitBuf[i] = (int) atol((const char *) splitBuf[i].c_str()); } // if } // for // Verify that the vector specified was an integer and that it was in the valid range of values. if ( retValidCommand ) { vecIndex = int_splitBuf[1]; subscript = int_splitBuf[2]; value = int_splitBuf[3]; if ( vecIndex < 0 || vecIndex > MAXV-1 ) { cerr << "ERROR: invalid vector specification '" << splitBuf[1] << "' entered for '" << buffer << "'." << endl; retValidCommand = false; } // if // Verify that the number of parameters for each command is valid, or it is a comment. if ( (command == FETCH && numSplit != 3) || (command == ASSIGN && numSplit != 4) || (command == STATUS && numSplit != 2) ) { cerr << "ERROR: invalid number of parameters for '" << buffer << "'." << endl; retValidCommand = false; } else if ( command != COMMENT && command != FETCH && command != ASSIGN && command != STATUS ) { cerr << "ERROR: unknown command '" << buffer << "' entered." << endl; retValidCommand = false; } // if } // if } // if return retValidCommand; } // ParseCommand //-------------------------------------------------------------------------------------------------------------------- // Main driver for the program. Reads in the commands and calls the appropriate routines. //-------------------------------------------------------------------------------------------------------------------- int main() { char command; // Command read in by the driver. int subscript; // Subscript for the vector. int value; // Value to be assigned. FlexVec myList[MAXV]; // Simulated vectors of integers. int vecIndex; // Which vector is to be modified. int numEntries; // Number of non-zero entries in the list. int maxIndex; // Maximal subscript so far for non-zero entry. int minIndex; // Minimal subscript so far for non-zero entry. cin >> noskipws; // Turn off white space skipping. for ( ;; ) { string buffer = ""; // Throw-away buffer for rest of line. getline( cin, buffer ); if ( cin.fail() ) break; if ( ParseCommand( buffer, command, vecIndex, subscript, value ) ) { switch ( command ) { case FETCH: cout << "FETCH returns " << (myList[vecIndex])[subscript] << endl; break; case ASSIGN: (myList[vecIndex])[subscript] = value; break; case STATUS: myList[vecIndex].Status(numEntries, minIndex, maxIndex); cout << "Vector" << vecIndex << " has " << numEntries << " non-zero entries."; if (numEntries > 0) { cout << " Vector subscripts are in the range [" << minIndex << ", " << maxIndex << "]."; } // if cout << endl; break; case COMMENT: // do nothing break; default: break; } // switch } // if } // for } // main // Local Variables: // compile-command: "g++ -g -o flexvec classes.C flexvec.C" // End: