Week 5

Functions

Exercise 5.1

Write a function named censor that replaces all occurrences of a string within another string by a specified character, which by default should be an asterisk, and prints the censored string. You may assume that the string to be censored is not empty.

For example, the function call

censor("Hello world!", "world");

should print

Hello *****!

and the function call

censor("Meet me at the meeting place.", "me", '@');

should print

Meet @@ at the @@eting place.

(Note that the Me in Meet is not censored since the M is capitalized, but the me in meeting is.)

It is possible that the string to replace does not occur in the other string; for example,

censor("Hello everyone!", "world");

would just print

Hello everyone!

Hint: Use the find and replace functions from the <string> library.

Solution

Here is one possible solution. (This was the solution devised during the discussion section.)

void censor(string sentence, string word, char c) {
    int len = word.length();

    while (true) {
        int pos = sentence.find(word);

        if (pos != string::npos) {
            sentence.replace(pos, len, len, c);
        }
        else {
            break;
        }
    }

    cout << sentence;
}

Alternative solution

Here is another possible solution. Note that the while loop in this solution has a conditional statement such that a break statement is not required in the body of the loop.

void censor(string sentence, string word, char c) {
    size_t pos;
    size_t len = word.length();

    while ((pos = sentence.find(word)) != string::npos) {
        sentence.replace(pos, len, len, c);
    }

    cout << sentence;
}

For the meaning of size_t, see here.

References

Exercise 5.2

(a) What is the output of the following program?

#include <iostream>
#include <string>

using namespace std;

void function(string s) {
    cout << "In function: " << s << '\n';
    s = "Goodbye world";
    cout << "In function: " << s << '\n';
}

int main() {
    string s = "Hello world";

    cout << "In main: " << s << '\n';
    function(s);
    cout << "In main: " << s << '\n';

    return 0;
}
Solution

In main: Hello world
In function: Hello world
In function: Goodbye world
In main: Hello world


(b) What is the output of the following program? (This program is identical to the one in part (a), except that the type of the parameter s has been changed. Does this change the output?)

#include <iostream>
#include <string>

using namespace std;

void function(string& s) {
    cout << "In function: " << s << '\n';
    s = "Goodbye world";
    cout << "In function: " << s << '\n';
}

int main() {
    string s = "Hello world";

    cout << "In main: " << s << '\n';
    function(s);
    cout << "In main: " << s << '\n';

    return 0;
}
Solution

In main: Hello world
In function: Hello world
In function: Goodbye world
In main: Goodbye world

Notice that s in main has the value Goodbye world after the function call. This is because s was passed by reference to function, so the assignment to s in function changed the value of s in main.


(c) What is the output of the following program? (This program is identical to the one in part (b), except that the name of the function parameter has been changed. Does this change the output?)

#include <iostream>
#include <string>

using namespace std;

void function(string& t) {
    cout << "In function: " << t << '\n';
    t = "Goodbye world";
    cout << "In function: " << t << '\n';
}

int main() {
    string s = "Hello world";

    cout << "In main: " << s << '\n';
    function(s);
    cout << "In main: " << s << '\n';

    return 0;
}
Solution

In main: Hello world
In function: Hello world
In function: Goodbye world
In main: Goodbye world

The output is identical to that of part (b), since the parameter is still a reference to s in main.