/** This file defines and demonstrates two necessary components for
* the hash table lab for CS 2150. The first is the use of the
* getWordInGrid() function, which is used for retrieving a word in a
* grid of letters in one of the cardinal 8 directions (north,
* south-east, etc). The second is the use of file streams to read in
* input from a file, specifically one formatted as per the lab 6
* guidelines.
*
* Written by Aaron Bloomfield, 2009
*/
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
// We create a 2-D array of some big size, and assume that the grid
// read in will be less than this size (a valid assumption for lab 6)
#define MAXROWS 500
#define MAXCOLS 500
char grid[MAXROWS][MAXCOLS];
// Forward declarations
bool readInGrid (string filename, int &rows, int &cols);
char* getWordInGrid (int startRow, int startCol, int dir, int len,
int numRows, int numCols);
/** The main() function shows how to call both the readInGrid()
* function as well as the getWordInGrid() function.
*/
int main() {
// to hold the number of rows and cols in the input file
int rows, cols;
// attempt to read in the file
bool result = readInGrid ("5x8.grid.txt", rows, cols);
// if there is an error, report it
if ( !result ) {
cout << "Error reading in file!" << endl;
exit(1); // requires the <stdlib.h> #include header!
}
// Get a word (of length 10), starting at position (2,2) in the
// array, in each of the 8 directions
cout << endl;
for ( int i = 0; i < 8; i++ )
cout << i << ": " << getWordInGrid(2,2,i,10,rows,cols) << endl;
// All done!
return 0;
}
/** This function will read in a grid file, as per the format in the
* CS 2150 lab 6 document, into a global grid[][] array. It uses C++
* file streams, and thus requires the the <fstream> #include header.
*
* @return true or false, depending on whether the file was
* successfully opened.
* @param filename The file name to read in -- it's assumed to be in
* the file format described in the lab document.
* @param rows The number of rows as specified in the input file;
* as this is a reference, it is set by the function.
* @param cols The number of columnss as specified in the input file;
* as this is a reference, it is set by the function.
*/
bool readInGrid (string filename, int &rows, int &cols) {
// a C++ string to hold the line of data that is read in
string line;
// set up the file stream to read in the file (takes in a C-style
// char* string, not a C++ string object)
ifstream file(filename.c_str());
// upon an error, return false
if ( !file.is_open() )
return false;
// the first line is the number of rows: read it in
file >> rows;
cout << "There are " << rows << " rows." << endl;
getline (file,line); // eats up the return at the end of the line
// the second line is the number of cols: read it in and parse it
file >> cols;
cout << "There are " << cols << " cols." << endl;
getline (file,line); // eats up the return at the end of the line
// the third and last line is the data: read it in
getline (file,line);
// close the file
file.close();
// convert the string read in to the 2-D grid format into the
// grid[][] array. In the process, we'll print the grid to the
// screen as well.
int pos = 0; // the current position in the input data
for ( int r = 0; r < rows; r++ ) {
for ( int c = 0; c < cols; c++ ) {
grid[r][c] = line[pos++];
cout << grid[r][c];
}
cout << endl;
}
// return success!
return true;
}
/** This function will retrieve a word in a grid of letters in a given
* direction. If the end of the grid is encountered before the length
* of the desired string is reached, then a shorter string will be
* returned. The data is retrieved from a global char grid[][]
* array, which is assumed to be defined (and in scope). NOTE: The
* return value is a static char[][] variable (for efficiency
* reasons), so a successive return value will overwrite a previous
* return value.
*
* @return A char* containing the letters in the provided direction
* (NOTE: it is returned in a static char array).
* @param startRow The starting (row,col) position to find the word.
* @param startCol The starting (row,col) position to find the word.
* @param dir The direction to move: 0 is north (upwards), 1 is
* northeast, and it rotates around clockwise until it
* reaches 7 for northwest.
* @param len The desired length of the string to return (assuming
* the edge of the grid is not reached--if the edge of the
* grid is reached, it will return as many characters as
* possible up to the edge of the grid, so the returned
* string may not have the same length as this parameter
* indicates).
* @param numRows The number of rows in the global char grid[][]
* array.
* @param numCols The number of columns in the global char grid[][]
* array.
*/
char* getWordInGrid (int startRow, int startCol, int dir, int len,
int numRows, int numCols) {
// the static-ness of this variable prevents it from being
// re-declared upon each function invocataion. It also prevents it
// from being deallocated between invocations. It's probably not
// good programming practice, but it's an efficient means to return
// a value.
static char output[256];
// make sure the length is not greater than the array size.
if ( len >= 255 )
len = 255;
// the position in the output array, the current row, and the
// current column
int pos = 0, r = startRow, c = startCol;
// iterate once for each character in the output
for ( int i = 0; i < len; i++ ) {
// if the current row or column is out of bounds, then break
if ( (c >= numCols) || (r >= numRows) || (r < 0) || (c < 0) )
break;
// set the next character in the output array to the next letter
// in the grid
output[pos++] = grid[r][c];
// move in the direction specified by the parameter
switch (dir) { // assumes grid[0][0] is in the upper-left
case 0:
r--;
break; // north
case 1:
r--;
c++;
break; // north-east
case 2:
c++;
break; // east
case 3:
r++;
c++;
break; // south-east
case 4:
r++;
break; // south
case 5:
r++;
c--;
break; // south-west
case 6:
c--;
break; // west
case 7:
r--;
c--;
break; // north-west
}
}
// set the next character to zero (end-of-string)
output[pos] = 0;
// return the string (a C-style char* string, not a C++ string
// object)
return output;
}