\documentclass[11pt]{article} \usepackage{times} \usepackage{fancyheadings} \pagestyle{fancy} \textwidth=6.5in \oddsidemargin=0in \setlength{\headwidth}{\textwidth} % This shouldn't be needed. ?? \lhead{\footnotesize CS 1723, Data Structures, Assignment 4, \today} \rhead{\footnotesize Page \thepage~~of~~\pageref{'thatsall'}} \lfoot{} \chead{} \cfoot{} \rfoot{} \newcommand{\ttb}{\fontfamily{pcr}\fontseries{b}\fontshape{n}% \fontsize{11}{13pt}\selectfont} %Courier bold at 11pt \newcommand{\longst}{\rule[-3mm]{0mm}{2mm}} \newcommand{\st}{\rule[-.8mm]{0mm}{2mm}} \newcommand{\mywidth}{6.5in} \newcommand{\myrightmar}{0.2in} \newcommand{\myleftmar}{0.4in} \newcommand{\myparsep}{2mm} \newcommand{\mynegvertsp}{-0.35in} \newcommand{\myvspace}{-0.2in} \textwidth \mywidth \parindent 10mm \parskip 3mm \columnsep=6mm %%%10mm \topmargin=0in \textheight=9in \oddsidemargin=0in \evensidemargin=0in \begin{document} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % make everything sloppy \sloppy %\thispagestyle{empty} \begin{center} %{\large\bf The University of Texas at San Antonio \\ %Computer Science Program \\ %San Antonio, Texas 78249} \\ %\vspace{0.4in} {\large\bf CS 1723, Data Structures \\ Spring Semester, 1997\longst \\ Programming Assignment 4\longst } \\ {\large\it Finding Words in a String \\ Due February 28, 1997} \end{center} \noindent {\bf The Assignment:} Start with a reference string {\ttb ref} of letters and an on-line dictionary of words. For example, {\ttb ref} might be {\ttb "horseshouses"}. You are to write a program which will find all dictionary words that can be made up from letters in the reference string. Notice that you can only use as many of each kind of letter as actually appear in the reference string: in the example above, up to 2 {\ttb "o"}s, 4 {\ttb "s"}s, 2 {\ttb "e"}s, and 2 {\ttb "h"}s, but only one {\ttb "u"} and one {\ttb "r"}. Thus your program must {\em not} find a word like {\ttb "usurer"} that has 2 {\ttb "u"}s in it or like {\ttb "sorrow"} that has 2 {\ttb "r"}s in it. Using the supplied large dictionary, over 50 entries will be found from this particular reference string, including {\ttb "horseshoe"}, {\ttb "osseous"}, and {\ttb "rhesus"}. \noindent {\bf The Program:} You may use a single file for your program. Make a new directory, {\ttb assign4}, and store the source file there as {\ttb findwords.c}. The organization of {\ttb findwords.c} should be similar to the following steps: \vspace{-0.2in} \begin{list}{dummy}{\parsep=1mm \itemsep=1mm} \item[1.] Obtain the name of the dictionary file from a command line argument. \item[2.] Open the dictionary file, for reading. Open a file for writing to store the words found. \item[3.] Prompt the user for the reference string, {\ttb ref}. \item[4.] Read the reference string. \item[5.] Read each line of the dictionary file, from the file opened for reading in step 2. \item[6.] Check if each dictionary entry can be made up from the letters of {\ttb ref}. \item[7.] If it can be made up from {\ttb ref}, insert this entry into a growing array of pointers to strings, {\ttb tab}. \item[8.] Each entry found should also be written to a file opened for writing in step 2. \item[9.] At end-of-file on the dictionary file, inform the user of the number of words found that can be made up from {\ttb ref}. Query the user if the words should be displayed. If {\ttb "yes"}, then print the contents of the array of pointers. \item[10.] Close the two files from step 2. \end{list} \noindent {\bf Details:} \vspace{-0.2in} \begin{list}{dummy}{\parsep=1mm \itemsep=1mm} \item[1.] Use the following format for a command: \hspace*{17mm}{\tt runner\% {\ttb findwords -d words}} Your text (the white book) tells how to extract these arguments (Section 5.10, pages 114 on). {\ttb argv[0]}, which is {\ttb "findwords"} and {\ttb argv[1]}, which is {\ttb "-d"}, can be ignored, but {\ttb argv[2]} should be the name of the dictionary file. \item[2.] The actual 50~000 word dictionary (200K bytes) is \hspace*{17mm}{\ttb \verb1~1wagner/pub/CS1723/words} You {\em must not} make a copy of this file, but instead {\em must} set up a {\em symbolic link} to it with the command: \hspace*{17mm}{\tt runner\% {\ttb ln -s \verb1~1wagner/pub/CS1723/words words}} The command should be executed inside your {\ttb assign3} directory. Afterwards any reference to {\ttb "words"} in this directory is translated to a reference to my dictionary. In case of a mistake, you can remove the symbolic link with a {\ttb rm} command, just as you would remove an ordinary file. (Of course, this {\rm} will only remove the {\em link} and not the file linked to.) The file opening will {\em not} work with \hspace*{17mm}{\ttb"\verb1~1wagner/pub/CS1723/words"} in the {\ttb fopen()} function. The full path name \hspace*{17mm}{\ttb"/home/faculty/wagner/pub/CS1723/words"} {\em will} work, but I want you to practice using symbolic links. The dictionary itself is just a list of words, and includes entries that are not normally considered English words, such as an entry for each single letter, and entries which are acronyms. The {\ttb FILE} declarations, and the opening of these two files should be handled with {\ttb fopen()}, as described in the white book (Section 7.5, page 160 and Section B1.1, page 242). \item[3.] To ``prompt the user'' means to write a short message to {\ttb stdout}. \item[4.] Read the characters of the reference string {\ttb ref} from {\ttb stdin}. \item[5.] I suggest that you use {\ttb fgetc()} to read a line (= record or entry) of the dictionary, character-at-a-time, until the newline. You must insert the null character yourself. You could mimic the white book's {\ttb getline()} function (page 29), except that you are not reading from {\ttb stdin}, and you do {\em not} want to insert a newline into the string you are reading (as {\ttb getline()} does). \item[6.] This is actually fairly hard to think through. There are many methods. Don't worry about efficiency. We will discuss several approaches in class. \item[7.] Once you have identified a dictionary entry that can be made up from the letters of the reference string, you are to insert this new string into {\ttb tab}, an array of pointers to {\ttb char}. The white book, pages 108-109, shows this, though you should use {\ttb malloc()} to allocate storage for each string. \item[8.] I suggest that you write character-at-a-time, using {\ttb fputc()}. Don't forget to write the newline. \item[9.] Page 109, bottom, shows one way to write this out. \end{list} \noindent {\bf Debugging Notes:} Of course you should use a {\ttb makefile} and {\ttb lint}, as we have been doing. To keep from going crazy with this assignment, you should get the pieces working {\em separately}. Try out the fetch of the third command line argument. Create a short test dictionary {\ttb "testwords"} to use, and first just try opening it and reading from it. Then try storing its entries into an array of pointers to {\ttb char}. Separately, exercise your function that checks if a given word can be made up from the characters in the reference string. When you open a file with {\ttb fopen()}, a {\ttb NULL} pointer is returned if there is any trouble. The failure of an open is common, since the slightest mistake in the file name will cause failure. So you should {\em always} check for this null pointer. \noindent {\bf Required Execution:} For full credit it will be enough to execute this program with {\ttb "horseshouses"} as the reference string. Again for full credit your program should have all the various features mentioned in items 1 through 10 above. Some of these I will just have to check by looking at the code. %{\bf Extra Credit, if Bored with the Assignment:} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \label{'thatsall'} \end{document}