In my code, I am trying to prompt the user to input their name, social security number, userID, and password, while outputting the social security number in "xxx-xx-xxx" format, essentially replacing all numbers to x, and the characters in their password to x as well.

Though, I'm severely stuck on the initial social security portion, as while I am testing it, the code compiles, but it terminates. I think my problem is that I am troubled with the looping. Should I be making a function for this to loop, or is this just entirely wrong? Can someone explain the string::replace() function to me, as well as the string::insert() function?

I get the jist of it, but putting it into practice is where I feel like I am failing miserably!

Here is what I have so far:

#include <iostream>
#include <string>
using namespace std;

string topSecret(string);//prototype for topSecret function after main

int main()
{
    //Top Secret Input
    string name, social, userName, password;
    cout << "Enter your first name, Social Security number (digits only), userID (no spaces within ID), and password (no spaces within password) - with a space between each entry: ";
    cin >> name >> social >> userName >> password;
    cout << "Name: " << name << endl;
    cout << "SSN: " << social.replace(0,social.length(), "X");
    cout << "SSN: " << social.insert(2,"-") << endl;
    cout << "UserID: " << userName << endl;
    cout << "Password: " << topSecret(password) << endl;

    return 0;
}//end main

string topSecret (string password)//replace all characters in password to an X
{
    string::size_type length;
    string::size_type pw;
    for (pw = 0; pw < password.length(); pw++)//for the duration of the password
    {
    }//end for loop
}//end topSecret
3

There are 3 best solutions below

3
On BEST ANSWER

FYI, any time you don't understand a C++ function, you can google it, and you should find a great explanation at cplusplus.com pop up. That's where I got the information I'm about to tell you.

EDIT: As another stated, cppreference.com should also show up, and that's the place to look as well. I forgot to include it, haha

string::replace takes a start position, a length, and a string to replace it with.

What you seem to want is a function that can take an input value, and replace it with whatever you'd like. In this case, it seems you'd like to replace any number or character that isn't '-', correct?

In this case, I'd make a function that takes a string reference, a "shouldReplace" function, and a value to replace it with as inputs.

You said you're a beginner, so just in case, I'll explain what a reference is. Essentially, if you pass in a variable into a function and change it, then you won't actually be changing that variable, you'll be changing a copy of the variable. This is called "passing by value." If you instead pass by reference, then you any changes you make will actually effect what you do.

Our function is going to take in the input string and modify it, as this is the simplest route since string::replace already does that.

The next thing to explain is how to pass a function as a parameter. Again, since you said you're a beginner, I'm assuming you don't know this. Functions can be stored in variables and passed in like they're parameters. We want to make a function that given a character produces a boolean on whether the character should be replaced or not, and then we want to pass that into our replace function.

Now the meat and potatoes; the replace function.

First, we'll declare the function with the parameters as I mentioned:

#include <functional>
#include <string>

void conditionalReplaceWith(
        string &str, std::function<bool(char)> test, std::string repWith) {
    ...
}

Note that to get the string reference we use &str and to get the function we use a part of the standard library std::function and we declare it to return a bool and take a char as a parameter.

This means when we pass a function in, it should look like this:

bool testFuncToPassIn(char c) {
    ...
}

Now that we have a function, let's fill it in.

We want to loop over every character and test to see if it's a character we want to replace. If it is, then we replace it. If it isn't then we continue.

There's a better way to do this using stringstreams, but since you implied you're trying to do string::replace, I've made use of that instead.

I'd also use const references, but since you're a beginner, it's not worth explaining at this point. You don't need to know that yet.

#include <functional>
#include <string>

void conditionalReplaceWith(
        string &str, std::function<bool(char)> test, std::string repWith) {
    // Loop over every character. This will work even after modifying str
    for(int pos = 0; pos < str.length(); pos++) {
        if(test(str[pos])) { // Check if the character should be replaced
            str.replace(pos, 1, repWith); // Replace it! Increases str.length()
        }
    }
}

Now we need our test functions:

bool isNotDash(char c) {
    return c != '-';
}

Let's put it all together:

#include <iostream>
#include <functional>
#include <string>

void conditionalReplaceWith(
        string &str, std::function<bool(char)> test, std::string repWith) {
    // Loop over every character. This will work even after modifying str
    for(int pos = 0; pos < str.length(); pos++) {
        if(test(str[pos])) { // Check if the character should be replaced
            str.replace(pos, 1, repWith); // Replace it! Increases str.length()
        }
    }
}

bool isNotDash(char c) {
    return c != '-';
}

int main() {
    std::string name, social, userName, password;
    std::cout << "Enter your first name, Social Security number (digits only), userID (no spaces within ID), and password (no spaces within password) - with a space between each entry: ";
    std::cin >> name >> social >> userName >> password;
    
    conditionalReplaceWith(social, isNotDash, "X");
    ...
}

Finally, if you want to make your top secret function use the conditionalReplaceWith, you can do something like:

std::string topSecret(std::string password) {
    conditionalReplaceWith(password, [](char c) { return true; }, "X");
    return password;
}

That little [](char c) { return true; } is an anonymous function. It declares a function right there.

Anyway, this does not change password because, remember, password is passed by value. Modifying it here is like saying std::string passwordCopy(password) and making a copy of it first.

So yeah. There you go.

0
On

Okay :] so yall, I got this to output in a very meaningful way all thanks to your contributions and some reading on my end. I also went to the cppreference site to read more. So thank you for that! This is my new and improved code..please let me know what yall think...

#include <iostream>
#include <string>
using namespace std;

bool isNotDash(char);//prototype for isNotDash
string xOut(string);//prototype for xOut function
string topSecret(string);//prototype for topSecret function after main

int main()
{
    //Top Secret Input
    string name, social, userName, password;
    cout << "Enter your first name, Social Security number (000-00-000 format), userID (no spaces within ID), and password (no spaces within password) - with a space between each entry: ";
    cin >> name >> social >> userName >> password;
    cout << "Let's cover some of this up, shall we..." << endl;
    cout << "Name: " << name << endl;
    cout << "SSN: " << xOut(social) << endl;//calls xOut function to use as the output
    cout << "UserID: " << userName << endl;
    cout << "Password: " << topSecret(password) << endl;//calls topSecret function to use as output

    return 0;
}//end main

bool isNotDash(char n) //checks to see if within string social, is it a dash or number
{
    return n != '-'; // return any character that is not a dash - which would be a number
}//end isNotDash

string xOut(string social) // replace with X
{
    for(int x = 0; x < social.length(); x++)//loop through string
        {
            if(isNotDash (social.at(x)))// calls isNotDash function to check to see if character, that is not a dash, should be replaced
        {
            social.replace(x, 1, "X"); // start at position x, iterate, and x it out
        }//end if
    }
    return social;
}//end xOut function



string topSecret (string password)//replace all characters in password to an X
{
    string::size_type length;
    for (int pw = 0; pw < password.length(); pw++)//declare and initialize integer pw to 0, as long as it does not exceed the length of password - loop
    {
        password.replace(pw, 1, "X");//start at pos pw, iterate, and replace with x
    }//end for loop
    return password;
}//end topSecret
1
On

The topSecret() function is not doing anything besides iterating the string, and it does not return any value - you should be getting a compilation warning from this.

A function that does not specify void as its return value must always return something, and not doing so causes undefined behavior. In this case, the instance of std::string that operator<<() is attempting to print probably ends up referring to invalid memory, thus causing a crash.