Pastebin launched a little side project called VERYVIRAL.com, check it out ;-) Want more features on Pastebin? Sign Up, it's FREE!
Guest

string215.cpp

By: a guest on Mar 1st, 2013  |  syntax: C++  |  size: 9.86 KB  |  views: 78  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1.  
  2.  
  3. #include <iostream>
  4. #include <cstring>
  5. #include "string215.h"
  6. using namespace std;
  7.  
  8. int test_string215();
  9. void pause_215(bool have_newline);
  10.  
  11. int string215::str_len(const char *str) const
  12. {
  13.         int len = 0;
  14.         const char *search;
  15.         for(search = str; *search != '\0'; search++) {
  16.                 len++;
  17.         }
  18.         return len;
  19. }
  20.  
  21. // Make and return a dynamically-allocated copy of the input C string.
  22. char *string215::copy_string(const char *input)
  23. {
  24.         char *output = new char[str_len(input)+1];
  25.  
  26.         for(const char *scan = input; *scan != '\0'; scan++) {
  27.                 *output = *scan;
  28.                 output++;
  29.         }
  30.         *output = '\0';
  31.         if(str_len(input) > 0) {
  32.                 output -= str_len(input);
  33.         }
  34.         return output;
  35. }
  36.  
  37. // Return true if the two C strings contain the same sequence of characters.
  38. bool string215::equal_string(const char *first, const char *second) const
  39. {
  40.         const char *scan1;
  41.         const char *scan2;
  42.  
  43.         if(str_len(first) == str_len(second)) {
  44.                 scan1 = first;
  45.                 scan2 = second;
  46.                 while(*scan1 != '\0') {
  47.                         if(*scan1 != *scan2) {
  48.                                 return false;
  49.                         }
  50.                         scan1++;
  51.                         scan2++;
  52.                 }
  53.                 return true;
  54.         }
  55.         return false;
  56. }
  57.  
  58. // Destructor for the string215 class
  59. string215::~string215()
  60. {
  61.         delete[] data;
  62. }
  63.  
  64. // Constructor for thwe string215 class
  65. string215::string215()
  66. {
  67.         char *arr = new char[0];
  68.         arr[0] = '\0';
  69.         data = arr;
  70. }
  71.  
  72. // A copy constructor that allocates memory and performs a deep copy of the input object
  73. string215::string215(const string215 &other)
  74. {
  75.         data = copy_string(other.data);
  76. }
  77.  
  78. // Check whether two strings contain the same characters.
  79. bool string215::equals(const string215 &other) const
  80. {
  81.         if(equal_string(data, other.data) == true) {
  82.                 return true;
  83.         }
  84.         return false;
  85. }
  86.  
  87. // Return the length of a string215, not counting the null terminator.
  88. int string215::length() const
  89. {      
  90.         return str_len(data);
  91. }
  92.  
  93. // Return the character at a given index.  Returns '\0' if the
  94. // index is out of bounds.
  95. char string215::getchar(int index) const
  96. {
  97.         const char *stepper = data;
  98.         if(index <= str_len(data) && index >= 0) {
  99.                 for(int x = 0; x < index; x++) {
  100.                         stepper++;
  101.                 }
  102.                 return *stepper;
  103.         }
  104.         return '\0';
  105. }
  106.  
  107. // Set the character at a given index and return false.
  108. bool string215::setchar(int index, char newchar)
  109. {
  110.         if(index <= str_len(data) && index >= 0) {
  111.                 for(int x = 0; x < index; x++) {
  112.                         data++;
  113.                 }
  114.                 *data = newchar;
  115.                 return true;
  116.         }
  117.         return false;
  118. }
  119.  
  120. // Add a suffix to the end of this string.  Allocates and frees memory.
  121. void string215::append(const string215 &suffix)
  122. {
  123.         char *output = new char[str_len(data)+suffix.length()+1];
  124.         for(int x = 0; x < str_len(data); x++) {
  125.                 *output = *data;
  126.                 output++;
  127.                 data++;
  128.         }
  129.  
  130.         for(int x = 0; x < suffix.length(); x++) {
  131.                 *output = suffix.getchar(x);
  132.                 output++;
  133.         }
  134.         *output = '\0';
  135.         output -= (str_len(data)+suffix.length()+1);
  136.         delete[] data;
  137.         data = output;
  138. }
  139.  
  140. // Return a pointer to the raw character data (not a copy).
  141. const char *string215::c_str() const
  142. {
  143.         const char *pRaw = data;
  144.         return pRaw;
  145. }
  146.  
  147. // Create a string215 that is a (deep) copy of a C string.
  148. string215::string215(const char *in_str)
  149. {
  150.         data = copy_string(in_str);
  151. }
  152.  
  153. /* string215::replace() - Replace the contents of a string215 with the
  154. *                        contents of a C string.
  155. *
  156. * Description:
  157. *   Replace the contents of this string with a copy of the C string
  158. *   argument.  Allocates memory for the new string array, performs a
  159. *   deep copy of the input, and frees the old array.
  160. *
  161. * Inputs:
  162. *   const char *in_str - The C string to copy into this object.
  163. *  
  164. * Outputs:
  165. *   No return value.  The current string's contents are modified to be
  166. *   character-by-character identical with the C string.
  167. */
  168. void string215::replace(const char *in_str)
  169. {
  170.         delete[] data;
  171.         data = new char[str_len(in_str)+1];
  172. }
  173.  
  174.  
  175. /* test_string215() - Test the string215 class.
  176. *
  177. * Description:
  178. *   Run a number of tests of the various methods of the string215 class.
  179. *
  180. * Inputs:
  181. *   No inputs.
  182. *
  183. * Outputs:
  184. *   Prints a message about each failed test to cerr.  Returns the number of
  185. *   failed tests.
  186. */
  187. int test_string215()
  188. {
  189.         // Current test number.  Be sure to increment this before each test!
  190.         int curr_test = 0;
  191.         // Number of failed tests.
  192.         int failed = 0;
  193.  
  194.         // TODO: Add at least two additional tests for the append method;
  195.         // and four tests each for the setchar, equals, and replace methods.
  196.         // Test both normal and boundary conditions.  If the test failed,
  197.         // print a message to cerr and increment the 'failed' counter.
  198.         //
  199.         // Do not change or remove any of the existing tests!
  200.         //
  201.         // Note: This function is the only part of the program permitted to
  202.         // use the functions strcmp, strlen, and so on.
  203.  
  204.  
  205.         // Testing contents:
  206.         // Tests 1-8 cover the constructors and c_str().
  207.         // Tests 9-10 cover length().
  208.         // Tests 11-12 cover getchar().
  209.         // Tests 13-14 cover append().
  210.  
  211.         // Test 1: the default constructor and c_str().  An empty string
  212.         // should still be terminated with a '\0' (at position 0), and in
  213.         // particular should not be represented by a null pointer.
  214.         curr_test++;
  215.         string215 empty;
  216.         const char *cs = empty.c_str();
  217.         if (cs == NULL || cs[0] != '\0') {
  218.                 cerr << "Test " << curr_test << " failed." << endl;
  219.                 failed++;
  220.         }
  221.  
  222.         // Test 2: does the C string constructor faithfully copy its input?
  223.         curr_test++;
  224.         char letters[] = "some characters here";
  225.         string215 full(letters);
  226.  
  227.         if (strcmp(letters, full.c_str()) != 0) {
  228.                 cerr << "Test " << curr_test << " failed." << endl;
  229.                 failed++;
  230.         }
  231.  
  232.         // Test 3: and did it do a deep copy?  The pointers should
  233.         // differ.
  234.         curr_test++;
  235.         if (letters == full.c_str()) {
  236.                 cerr << "Test " << curr_test << " failed." << endl;
  237.                 failed++;
  238.         }
  239.  
  240.         // Test 4: make sure c_str() isn't making a copy.  If we call
  241.         // it twice in a row, it should return the same address.
  242.         curr_test++;
  243.         if (full.c_str() != full.c_str()) {
  244.                 cerr << "Test " << curr_test << " failed." << endl;
  245.                 failed++;
  246.         }
  247.  
  248.         // Test 5: make sure we can copy an empty string.
  249.         curr_test++;
  250.         string215 empty_fromc("");
  251.         cs = empty_fromc.c_str();
  252.         if (cs[0] != '\0') {
  253.                 cerr << "Test " << curr_test << " failed." << endl;
  254.                 failed++;
  255.         }
  256.  
  257.         // Test 6: test that the copy constructor copies.
  258.         curr_test++;
  259.         string215 full_copy(full);
  260.         if (strcmp(full_copy.c_str(), full.c_str()) != 0) {
  261.                 cerr << "Test " << curr_test << " failed." << endl;
  262.                 failed++;
  263.         }
  264.  
  265.         // Test 7: and that it does a deep copy.
  266.         curr_test++;
  267.         if (full_copy.c_str() == full.c_str()) {
  268.                 cerr << "Test " << curr_test << " failed." << endl;
  269.                 failed++;
  270.         }
  271.  
  272.         // Test 8: test the copy constructor on an empty string.
  273.         curr_test++;
  274.         string215 empty_copy(empty);
  275.         cs = empty_copy.c_str();
  276.         if (cs[0] != '\0' || cs == empty.c_str()) {
  277.                 cerr << "Test " << curr_test << " failed." << endl;
  278.                 failed++;
  279.         }
  280.  
  281.         // Test 9: test the length method.
  282.         curr_test++;
  283.         if (full.length() != strlen(full.c_str())) {
  284.                 cerr << "Test " << curr_test << " failed." << endl;
  285.                 failed++;
  286.         }
  287.  
  288.         // Test 10: also on an empty string.
  289.         curr_test++;
  290.         if (empty.length() != 0) {
  291.                 cerr << "Test " << curr_test << " failed." << endl;
  292.                 failed++;
  293.         }
  294.  
  295.         // Test 11: test getchar for the first and last characters.
  296.         curr_test++;
  297.         string215 str("testing");
  298.         if (str.getchar(0) != 't' || str.getchar(str.length() - 1) != 'g') {
  299.                 cerr << "Test " << curr_test << " failed." << endl;
  300.                 failed++;
  301.         }
  302.  
  303.         // Test 12: also on out-of-bounds indices.
  304.         curr_test++;
  305.         if (str.getchar(-1) != '\0' || str.getchar(str.length()) != '\0'
  306.                 || str.getchar(9999) != '\0')
  307.         {
  308.                 cerr << "Test " << curr_test << " failed." << endl;
  309.                 failed++;
  310.         }
  311.  
  312.         // Test 13: test that append works in a simple case.
  313.         curr_test++;
  314.         string215 suffix("123");
  315.         str.append(suffix);
  316.         if (strcmp(str.c_str(), "testing123") != 0) {
  317.                 cerr << "Test " << curr_test << " failed." << endl;
  318.                 failed++;
  319.         }
  320.  
  321.         // Test 14: and that it didn't modify its argument.
  322.         curr_test++;
  323.         if (strcmp(suffix.c_str(), "123") != 0) {
  324.                 cerr << "Test " << curr_test << " failed." << endl;
  325.                 failed++;
  326.         }
  327.  
  328.         // TODO: YOUR TESTS GO HERE
  329.  
  330.         // Finally, return the number of failed tests
  331.         return failed;
  332. }
  333.  
  334. /* pause_215() - Wait for the user to press ENTER.
  335. *
  336. * Description:
  337. *   Optionally read and discard the remainder of the user's last
  338. *   line of input.  Then, prompt the user to press ENTER, then
  339. *   read and discard another line of input.
  340. *
  341. * Inputs:
  342. *   bool have_newline:
  343. *     True if the user has already entered a newline that the
  344. *     program has not yet read.  If true, this function first
  345. *     discards remaining input up to and including that newline.
  346. *
  347. *   Reads two lines from standard input if have_newline is true,
  348. *   one line if it is false.  Lines are assumed to be less than
  349. *   two hundred characters long.
  350. *
  351. * Outputs:
  352. *   No return value.
  353. *
  354. *   Prints a prompt to standard output.
  355. *
  356. * Notes:
  357. *   This function is intended to be used at the end of a program,
  358. *   just before returning from main().  Reading another line of
  359. *   input prevents the console window from closing immediately.
  360. *
  361. *   In general, have_newline should be true if the last user input
  362. *   from cin used the extraction operator (>>), and false if there
  363. *   has been no user input or if the last input used getline().
  364. */
  365. void pause_215(bool have_newline)
  366. {
  367.         if (have_newline) {
  368.                 // Ignore the newline after the user's previous input.
  369.                 cin.ignore(200, '\n');
  370.         }
  371.  
  372.         // Prompt for the user to press ENTER, then wait for a newline.
  373.         cout << endl << "Press ENTER to continue." << endl;
  374.         cin.ignore(200, '\n');
  375. }
  376.  
  377. int main()
  378. {
  379.         int failed = test_string215();
  380.  
  381.         if (failed == 0)
  382.                 cout << "All tests passed successfully." << endl;
  383.         else
  384.                 cout << "Sorry, " << failed << " test(s) failed." << endl;
  385.  
  386.         pause_215(false);
  387.         // Remember that returning zero from main indicates success, while
  388.         // return anything else means that some kind of error occurred.
  389.         return failed;
  390. }