Advertisement
Guest User

string215.cpp

a guest
Mar 1st, 2013
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.86 KB | None | 0 0
  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. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement