Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstring>
- #include "string215.h"
- using namespace std;
- int test_string215();
- void pause_215(bool have_newline);
- int string215::str_len(const char *str) const
- {
- int len = 0;
- const char *search;
- for(search = str; *search != '\0'; search++) {
- len++;
- }
- return len;
- }
- // Make and return a dynamically-allocated copy of the input C string.
- char *string215::copy_string(const char *input)
- {
- char *output = new char[str_len(input)+1];
- for(const char *scan = input; *scan != '\0'; scan++) {
- *output = *scan;
- output++;
- }
- *output = '\0';
- if(str_len(input) > 0) {
- output -= str_len(input);
- }
- return output;
- }
- // Return true if the two C strings contain the same sequence of characters.
- bool string215::equal_string(const char *first, const char *second) const
- {
- const char *scan1;
- const char *scan2;
- if(str_len(first) == str_len(second)) {
- scan1 = first;
- scan2 = second;
- while(*scan1 != '\0') {
- if(*scan1 != *scan2) {
- return false;
- }
- scan1++;
- scan2++;
- }
- return true;
- }
- return false;
- }
- // Destructor for the string215 class
- string215::~string215()
- {
- delete[] data;
- }
- // Constructor for thwe string215 class
- string215::string215()
- {
- char *arr = new char[0];
- arr[0] = '\0';
- data = arr;
- }
- // A copy constructor that allocates memory and performs a deep copy of the input object
- string215::string215(const string215 &other)
- {
- data = copy_string(other.data);
- }
- // Check whether two strings contain the same characters.
- bool string215::equals(const string215 &other) const
- {
- if(equal_string(data, other.data) == true) {
- return true;
- }
- return false;
- }
- // Return the length of a string215, not counting the null terminator.
- int string215::length() const
- {
- return str_len(data);
- }
- // Return the character at a given index. Returns '\0' if the
- // index is out of bounds.
- char string215::getchar(int index) const
- {
- const char *stepper = data;
- if(index <= str_len(data) && index >= 0) {
- for(int x = 0; x < index; x++) {
- stepper++;
- }
- return *stepper;
- }
- return '\0';
- }
- // Set the character at a given index and return false.
- bool string215::setchar(int index, char newchar)
- {
- if(index <= str_len(data) && index >= 0) {
- for(int x = 0; x < index; x++) {
- data++;
- }
- *data = newchar;
- return true;
- }
- return false;
- }
- // Add a suffix to the end of this string. Allocates and frees memory.
- void string215::append(const string215 &suffix)
- {
- char *output = new char[str_len(data)+suffix.length()+1];
- for(int x = 0; x < str_len(data); x++) {
- *output = *data;
- output++;
- data++;
- }
- for(int x = 0; x < suffix.length(); x++) {
- *output = suffix.getchar(x);
- output++;
- }
- *output = '\0';
- output -= (str_len(data)+suffix.length()+1);
- delete[] data;
- data = output;
- }
- // Return a pointer to the raw character data (not a copy).
- const char *string215::c_str() const
- {
- const char *pRaw = data;
- return pRaw;
- }
- // Create a string215 that is a (deep) copy of a C string.
- string215::string215(const char *in_str)
- {
- data = copy_string(in_str);
- }
- /* string215::replace() - Replace the contents of a string215 with the
- * contents of a C string.
- *
- * Description:
- * Replace the contents of this string with a copy of the C string
- * argument. Allocates memory for the new string array, performs a
- * deep copy of the input, and frees the old array.
- *
- * Inputs:
- * const char *in_str - The C string to copy into this object.
- *
- * Outputs:
- * No return value. The current string's contents are modified to be
- * character-by-character identical with the C string.
- */
- void string215::replace(const char *in_str)
- {
- delete[] data;
- data = new char[str_len(in_str)+1];
- }
- /* test_string215() - Test the string215 class.
- *
- * Description:
- * Run a number of tests of the various methods of the string215 class.
- *
- * Inputs:
- * No inputs.
- *
- * Outputs:
- * Prints a message about each failed test to cerr. Returns the number of
- * failed tests.
- */
- int test_string215()
- {
- // Current test number. Be sure to increment this before each test!
- int curr_test = 0;
- // Number of failed tests.
- int failed = 0;
- // TODO: Add at least two additional tests for the append method;
- // and four tests each for the setchar, equals, and replace methods.
- // Test both normal and boundary conditions. If the test failed,
- // print a message to cerr and increment the 'failed' counter.
- //
- // Do not change or remove any of the existing tests!
- //
- // Note: This function is the only part of the program permitted to
- // use the functions strcmp, strlen, and so on.
- // Testing contents:
- // Tests 1-8 cover the constructors and c_str().
- // Tests 9-10 cover length().
- // Tests 11-12 cover getchar().
- // Tests 13-14 cover append().
- // Test 1: the default constructor and c_str(). An empty string
- // should still be terminated with a '\0' (at position 0), and in
- // particular should not be represented by a null pointer.
- curr_test++;
- string215 empty;
- const char *cs = empty.c_str();
- if (cs == NULL || cs[0] != '\0') {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 2: does the C string constructor faithfully copy its input?
- curr_test++;
- char letters[] = "some characters here";
- string215 full(letters);
- if (strcmp(letters, full.c_str()) != 0) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 3: and did it do a deep copy? The pointers should
- // differ.
- curr_test++;
- if (letters == full.c_str()) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 4: make sure c_str() isn't making a copy. If we call
- // it twice in a row, it should return the same address.
- curr_test++;
- if (full.c_str() != full.c_str()) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 5: make sure we can copy an empty string.
- curr_test++;
- string215 empty_fromc("");
- cs = empty_fromc.c_str();
- if (cs[0] != '\0') {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 6: test that the copy constructor copies.
- curr_test++;
- string215 full_copy(full);
- if (strcmp(full_copy.c_str(), full.c_str()) != 0) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 7: and that it does a deep copy.
- curr_test++;
- if (full_copy.c_str() == full.c_str()) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 8: test the copy constructor on an empty string.
- curr_test++;
- string215 empty_copy(empty);
- cs = empty_copy.c_str();
- if (cs[0] != '\0' || cs == empty.c_str()) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 9: test the length method.
- curr_test++;
- if (full.length() != strlen(full.c_str())) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 10: also on an empty string.
- curr_test++;
- if (empty.length() != 0) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 11: test getchar for the first and last characters.
- curr_test++;
- string215 str("testing");
- if (str.getchar(0) != 't' || str.getchar(str.length() - 1) != 'g') {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 12: also on out-of-bounds indices.
- curr_test++;
- if (str.getchar(-1) != '\0' || str.getchar(str.length()) != '\0'
- || str.getchar(9999) != '\0')
- {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 13: test that append works in a simple case.
- curr_test++;
- string215 suffix("123");
- str.append(suffix);
- if (strcmp(str.c_str(), "testing123") != 0) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // Test 14: and that it didn't modify its argument.
- curr_test++;
- if (strcmp(suffix.c_str(), "123") != 0) {
- cerr << "Test " << curr_test << " failed." << endl;
- failed++;
- }
- // TODO: YOUR TESTS GO HERE
- // Finally, return the number of failed tests
- return failed;
- }
- /* pause_215() - Wait for the user to press ENTER.
- *
- * Description:
- * Optionally read and discard the remainder of the user's last
- * line of input. Then, prompt the user to press ENTER, then
- * read and discard another line of input.
- *
- * Inputs:
- * bool have_newline:
- * True if the user has already entered a newline that the
- * program has not yet read. If true, this function first
- * discards remaining input up to and including that newline.
- *
- * Reads two lines from standard input if have_newline is true,
- * one line if it is false. Lines are assumed to be less than
- * two hundred characters long.
- *
- * Outputs:
- * No return value.
- *
- * Prints a prompt to standard output.
- *
- * Notes:
- * This function is intended to be used at the end of a program,
- * just before returning from main(). Reading another line of
- * input prevents the console window from closing immediately.
- *
- * In general, have_newline should be true if the last user input
- * from cin used the extraction operator (>>), and false if there
- * has been no user input or if the last input used getline().
- */
- void pause_215(bool have_newline)
- {
- if (have_newline) {
- // Ignore the newline after the user's previous input.
- cin.ignore(200, '\n');
- }
- // Prompt for the user to press ENTER, then wait for a newline.
- cout << endl << "Press ENTER to continue." << endl;
- cin.ignore(200, '\n');
- }
- int main()
- {
- int failed = test_string215();
- if (failed == 0)
- cout << "All tests passed successfully." << endl;
- else
- cout << "Sorry, " << failed << " test(s) failed." << endl;
- pause_215(false);
- // Remember that returning zero from main indicates success, while
- // return anything else means that some kind of error occurred.
- return failed;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement