Lab 1

Due January 28

Sample Reader code: SampleReaderCode

PROJECT OVERVIEW

The overall goal of this project is the development of a program for retrieving Bible verses from a set of sequential files containing the Bible text. The program will eventually use a Web based user interface. The user will supply the book, chapter, and verse to the program, and the program will display the verse.

This first handout only specifies the first part, the writing of a program that reads a Bible book, parsing it into verse and reference objects, and displaying a selected verse. This code will then be integrated into the complete project. Thus with this program will create a bible object, and allow you to retrieve verses. The starting code can be found here: SampleReaderCode.

PROJECT METHOD

You will implement the objects below, and then write a simple “wrapper” to test them. The wrapper is a command line program that has three or four parameters as follow:

skon@tarus% bible_lookup 8 4 11
RUTH 4
11 And all the people that were in the gate, and the elders, said, We are
witnesses. The LORD make the woman that is come into thine house like Rachel
and like Leah, which two did build the house of Israel: and do thou worthily
in Ephratah, and be famous in Bethlehem:
skon@tarus% bible_lookup 63 1 7 4
2 JOHN 1
7 For many deceivers are entered into the world, who confess not that Jesus
Christ is come in the flesh. This is a deceiver and an antichrist.
8 Look to yourselves, that we lose not those things which we have wrought, but
that we receive a full reward.
9 Whosoever transgresseth, and abideth not in the doctrine of Christ, hath not
God. He that abideth in the doctrine of Christ, he hath both the Father and
the Son.
10 If there come any unto you, and bring not this doctrine, receive him not into your house, neither bid him God speed:
skon@tarus% bible_lookup 69 3 5 3
Error – no such book
skon@tarus% bible_lookup 1 77 3 5
Error – No such chapter 77 in Genesis
skon@tarus% bible_lookup 1 50 82 5
Error – No such verse 82 in Genesis 50
skon@tarus% bible_lookup 1 50
Error – verse number is missing

Note the output format … Print out the book name and chapter, then each verse number before each book. This will require you to modify the sample code I gave you appropriately.

LEARNING GOALS

This project has the following learning goals:

  1. Sequential file search and retrieval

  2. C++ object oriented file handling
FILE FORMAT

The Bible text is one complete file with the entire bible.

The file is organized as a sequential file, with variable length records, one verse in each record. Each record has the following format:

  1. 1-2 character book number
  2. Colon
  3. 1-3 character chapter number
  4. Colon
  5. 1-3 character verse number
  6. 1 space
  7. Remainder of record is verse text.
Example verse records:

1:1:19 And the evening and the morning were the fourth day.

49:1:23 Which is his body, the fulness of him that filleth all in all.

50:4:4 Rejoice in the Lord alway: and again I say, Rejoice.

The records are ordered in verse order.

The file may be found in "/home/class/csc3004/Bible/kjv-complete". Do not copy this into your own account (it will count against your quota)! Open and read the file directly in the class directory in your program.

A sample program is available in “"/home/class/csc3004/biblereaderdemo” which, when prompted for a bible book number, displays a complete book. Create a new directory, and copy over the contents of the directory, and use “make” to build the program. Then try it out!

You can look into a file by using the Unix “od” (octal dump) command. Use the “-c” switch to see character data:

skon@tarus% od -c kjv-complete | more
0000000 1 : 1 : 1 I n t h e b e g
0000020 i n n i n g G o d c r e a t
0000040 e d t h e h e a v e n a n
0000060 d t h e e a r t h . \n 1 : 1
0000100 : 2 A n d t h e e a r t h


You can also view the raw byte data in decimal form:

skon@tarus% od -t d1 kjv-complete | more
0000000 49 58 49 58 49 32 73 110 32 116 104 101 32 98 1 01 103
0000020 105 110 110 105 110 103 32 71 111 100 32 99 114 101 97 116
0000040 101 100 32 116 104 101 32 104 101 97 118 101 110 32 97 110
0000060 100 32 116 104 101 32 101 97 114 116 104 46 10 49 58 49


And in hexadecimal form::

skon@tarus% od -t x1 kjv-complete | more
0000000 31 3a 31 3a 31 20 49 6e 20 74 68 65 20 62 65 67 31 3a 31 3a 31 20 49 6e 20 74 68 65 20 62 65 67
0000020 69 6e 6e 69 6e 67 20 47 6f 64 20 63 72 65 61 74 69 6e 6e 69 6e 67 20 47 6f 64 20 63 72 65 61 74
0000040 65 64 20 74 68 65 20 68 65 61 76 65 6e 20 61 6e 65 64 20 74 68 65 20 68 65 61 76 65 6e 20 61 6e
0000060 64 20 74 68 65 20 65 61 72 74 68 2e 0a 31 3a 31 64 20 74 68 65 20 65 61 72 74 68 2e 0a 31 3a 31


METHODS

Retrieve the code in “"/home/class/csc3004/sample_reader”. This includes the file “Makefile”, “sample_reader.cpp”, and “sample_reader.h”. This code simply reads the specified verse into a string. Your code is to upgrade this code so it uses at least three objects, a Bible object, a verse object and a reference object.

This code is compiled using a “Makefile”. A Makefile is simply a set of commands that tells how to make a certain project. This make building possibly complex systems easy. All you have to do is type “make” in the directory with the make file and source files, and the make program will use the Makefile to build the program. Then you can type the name of the program followed by the name of the book file you want to display:

skon@tarus% ./sample_reader 18
18:1:1 There was a man in the land of Uz, whose name was Job; and that man was perfect and upright, and one that feared God, and eschewed evil.
18:1:2 And there were born unto him seven sons and three daughters.
18:1:3 ...

You will use command line parsing to parse either 3 or 4 parameters to read in a book number, a chapter number, a verse number, and finally an optional number of verses. Note that the number of verses may span chapters, but you do not have to span books.

Note that the file includes book numbers, but this project requires that you convert the book number to a book name in the output. This will require a method to convert from a book number to a book name string.

Some of the classes you could use are shown below. You must support at least these features, but may add more as needed. Also - you could have the verse text be stored in dynamic memory, but if you do that you will need a destructor.

Your goal is to create a new solution with 4 CPP files:

  1. BibleReader .cpp, BibleReader .h
  2. Bible.cpp, Bible.h
  3. Verse.cpp, Verse.h
  4. Ref.cpp. Ref.h
The new solution will start by creating an object of class "Bible", which has a constructor to which you pass a file name string of where the Bible resides in the file system.

Header Guards See this: http://faculty.cs.niu.edu/~mcmahon/CS241/c241man/node90.html

biblereader.cpp - Main Line - simple code to test classes

// Sample code to test Bible classes
// Bible.cpp
#include "biblereader.h"
#include "Ref.h"
#include "Verse.h"
#include "Bible.h"
#include <iostream>
#include <fstream>
#include <string> 
#include <stdio.h>
#include <stdlib.h>

using namespace std;

main (int argc, char ** argv) {</sticky> <sticky>
 Bible kjv("/home/class/csc3004/Bibles/kjv-complete");      // Create instance of the Bible class
 Verse verse;
 int b,c,v;
 LookupResult result;
 cout << "Using Bible from:";
 kjv.display();
 // Get the verse to lookup
 cout <<"What book, chapter and verse?";
 cin >>b>>c>>v;	

 //Create a reference from the numbers
 Ref ref(b,c,v);

 // Look it up in the bible
 cout << "Looking up reference: ";
 ref.display();
 cout << endl;

 verse = kjv.lookup(ref,result);
 cout << "Result: " << endl;
 verse.display();
 cout << endl;
}

Ref.h Reference Class Header - Parse and Retrieve Reference Information

// Start of Ref.h
#include <string> 
#include <stdlib.h>
#ifndef Ref_H
#define Ref_H
using namespace std;

string GetNextToken(string&, const string&);

class Ref {
private:
   short    book, chap, verse;  // Reference information
public:
   Ref();       // Default constructor
   Ref(string s);       // Parse constructor - pass "3:5:7"
   Ref(const int,const int,const int);  // Construct from three integers;
   // Accessors
   int getBook();       // Access book number
   int getChap();       // Access chapter number
   int getVerse();      // Access verse number
   bool operator==(const Ref ); // Compare if two references equal
   void display();      // Display Reference
 // Your version must show actual book name
};
#endif//Ref_H

Verse.h - Verse Class Header - Parse and Retrieve Verse content

#include <string> 
#include <stdlib.h>
#include "Ref.h"
#ifndef Verse_H
#define Verse_H
using namespace std;
class Verse {
 private:
   Ref::Ref verseRef;           // The reference for this verse.
   string verseText;    // Actual verse text 

 public:
 // (You are free to use a String class)
   Verse();     // Default constructor
   Verse(const string s);       // Parse constructor - pass verse string
   // Accessors                                                                         
   string getVerse();
   Ref getRef(); // Display reference and verse on cout

   void display();      // Display ref & verse with line breaks.
   // This will call verseref.print().
};
#endif//Verse_H

Bible.h - Bible Header - Parse and Retrieve Bible content

#include "Ref.h"
#include "Verse.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>

#ifndef Bible_H
#define Bible_H
using namespace std;
   enum LookupResult { success, no_book, no_chapter, no_verse, other};
class Bible {   // A class for a version of the bible

 private:
   string infile;

 public: 

   Bible();     // Default constructor
   Bible(const string s);       // Constructor  pass a line from bible file
   const Verse lookup( Ref , LookupResult);     // Find a given verse in this Bible
                        // return the status
   const Ref::Ref  next(const Ref,
              LookupResult );   // Return the reference after this ref
   const Ref::Ref  prev(const Ref,
              LookupResult );   // Return the reference before this ref
   const string error(LookupResult);    // Return a String lookup error message
   void display();
};
#endif //Bible_H

ref.cpp - Parse and Retrieve Bible content - Partial code

// Ref.cpp
#include <iostream>
#include <string>
using namespace std;

#include "Ref.h"

// GetNextToken - general routine for getting next Token
// Parameters
//    str - string to search.  search is destructive, e.g. tken is removed.
//    delimiters - string list of characters to use a delimiters for tokens
//    returns - string token (removed from str)
//
string GetNextToken(string& str,
     const string& delimiters = " ")
{
  // Skip delimiters at beginning.                                             
  string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  // Find first "non-delimiter".                                               
  string::size_type pos     = str.find_first_of(delimiters, lastPos);

  // Found a token, remove it from string, and return it                       
  string next = str.substr(lastPos, pos - lastPos);
  string rest = str.substr(pos - lastPos + 1,string::npos);
  str = rest;
  return(next);
}

Ref::Ref() {book = 0; chap = 0; verse = 0;}  	// Default constructor

Ref::Ref(const string s){ 			// Parse constructor - pass "3:5:7"
  string rtext = s;
  // parse the reference - notice, currently no error checking!
  if (rtext.length() > 6) {
    // Get book number
    string strbook = GetNextToken(rtext,":");
    book = atoi(strbook.c_str());
    // Get the chapter number
    string strchap = GetNextToken(rtext,":");
    chap = atoi(strchap.c_str());
    // Get the verse number
    string strverse = GetNextToken(rtext," ");
    verse = atoi(strverse.c_str());
  }
}

   Ref::Ref(const int b,const int c,const int v){ 	// Construct from three integers;
 book = b;
 chap = c;
 verse = v;
 }
   // Accessors
   int Ref::getBook() {return book;};	// Access book number
   int Ref::getChap() {return chap;};	// Access chapter number
   int Ref::getVerse() {return verse;};	// Access verse number

   bool Ref::operator==(const Ref::Ref a) {	// Compare if two references equal
      bool result;			// < and > compares might also be useful
      result = (a.book == book) &&
         (a.chap == chap) &&
         (a.verse == verse);
      return result;
   }
   void Ref::display(){ 	// Display Reference
     cout << book << ":" << chap << ":" << verse;
   }
 // Your version must show actual book name


Verse.cpp - Partial code

#include <iostream>

#include "Verse.h"
using namespace std;
   Ref verseRef;        // The reference for this verse.                                                         
   string verseText;    // Actual verse text                                                                     
 // (You are free to use a String class)                                                                         
   Verse::Verse()  {    // Default constructor                                                                   
     verseText = "Uninitialized Verse!";
     verseRef = Ref();
   }
   Verse::Verse(const string s){ // Parse constructor - pass verse string                                        

   // Accessors                                                                         
   string getVerse() {

   }

   Ref getRef() {

   }}
   // Display the ref and verse oncout
   void Verse::display(){       // Display ref & verse                                                           
     verseRef.display();
     cout << " " << verseText;
 }

Bible.cpp - Partial code

#include "Ref.h"
#include "Verse.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>

#include "Bible.h" 

using namespace std;

Bible::Bible(){infile ="/home/class/csc3004/Bibles/kjv-complete";}      // Default constructor

Bible::Bible(const string s){ infile = s;}      // Constructor  pass a line from bible file

const Verse Bible::lookup( Ref , LookupResult ) // Find a given verse in this Bible
{ 
  Verse aVerse;
  // Get the verse .....
  // return the status
  return(aVerse);
}
const Ref::Ref  Bible::next(const Ref ref,
                      LookupResult result){};   // Return the reference after this ref

const Ref::Ref  Bible::prev(const Ref ref,
                      LookupResult result){};   // Return the reference before this ref

const string Bible::error(LookupResult result){};       // Return a String lookup error message

void Bible::display() {cout << "Bible: " << Bible::infile << endl;}

Sample Start Code

The beginnings of ALL these files, including the makefile, is in the class directory at cs.mvnu.edu in /home/class/csc3004/bibleclassdemo. Copy this to your folder to start with.

What to turn in on Moodle

Turn in your code listing and the result of several runs (captured). Show both cases that work, as well as cases where the verse or chapter searched for does not exist. Please structure and document your code appropriately. Plan to demo your solution in lab. (Feb. 4)

Topic revision: r8 - 2016-02-04 - JimSkon
 
This site is powered by the TWiki collaboration platformCopyright &© by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback