Source code for ./labs/lab06/code/getWordInGrid.cpp (via source-highlight)
/** 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>
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);
string 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;
return 1;
}
// 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;
}
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 columns 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) {
// try to open the file
ifstream file(filename);
// upon an error, return false
if (!file.is_open()) {
return false;
}
// first comes the number of rows
file >> rows;
cout << "There are " << rows << " rows." << endl;
// then the columns
file >> cols;
cout << "There are " << cols << " cols." << endl;
// and finally the grid itself
string data;
file >> data;
// 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] = data[pos++];
cout << grid[r][c];
}
cout << endl;
}
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 string variable (for efficiency
* reasons), so a successive return value will overwrite a previous
* return value.
*
* @return A STATIC string containing the letters in the provided direction.
* @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.
*/
string 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 invocation. 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 string output;
output.clear(); // Since it's static we need to clear it
output.reserve(256); // Can't set capacity in the constructor so do it the first time here
// the position in the output array, the current row, and the
// current column
int 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 += 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
}
}
return output;
}