Mohsin
Mohsin

Reputation: 351

C++: String formatting

This is my input string: Muhammad Ali 65445519 76 butterfly123

This is my desired output: Muhammad Ali xxx-xx-xxx 76 xxxxxxxxx

Note: Other than the social security number(65445519) everything can vary in length i.e. Name, UserID(76) and passoword(butterfly123).

example:

Kobe Bryant 34567890 548 56mamba

I've given it a try BUT I have a fixed User ID of length 2. Can anyone come up with a solution in which the User ID can also vary? or a whole new different approach? I don't want to use string streams, in which you take the input one by one and then process the string respectively. However an effective and short string stream solution will be appreciated. Thanks.

string s;
int j;
getline(cin,s);
for (int i=0; i<s.length(); i++)
{
    if(s.at(i)=='0' || s.at(i)=='1' || s.at(i)=='2'
        || s.at(i)=='3' || s.at(i)=='4' || s.at(i)=='5'
        || s.at(i)=='6' || s.at(i)=='7' || s.at(i)=='8'
        || s.at(i)=='9')
    {
        s.replace(i,8,"xxxxxxxx");
        s.insert(i+3,"-");
        s.insert(i+6,"-");
        j=i+14;
        break;
    }
}
for(j;j<s.length();j++)
{
    s.replace(j,1,"x");
}
cout<<s<<endl;

Upvotes: 1

Views: 175

Answers (3)

Sam Varshavchik
Sam Varshavchik

Reputation: 118435

Yes, you should try a different approach.

Consider the following input

Sam123456789 FarkenParker 221778833 46 foobar

Your approach will end up replacing "123456789" with X-s, which is clearly wrong.

The correct approach:

1) Split the single string into whitespace-delimited words. Use std::array<std::string, 4>, or std::vector<std::string>, whatever works for you.

2) Simply replace the 2nd and the 5th word accordingly.

3) Then combine everything back, into a single string.

Upvotes: 1

ForceBru
ForceBru

Reputation: 44906

You don't really have to use getline(cin,s);, you can read the data into separate variables:

std::string name, surname, password;
unsigned long long security, ID;

std::cin >> name >> surname >> security >> ID >> password;

std::string processed_security, processed_pwd(password.size(), 'x');

while (security) processed_security += "x", security /= 10;

std::cout << name << surname << processed_security << ID << processed_pwd << std::endl;

Some notes on this code:

  1. You can use a smaller unsigned integer datatype for ID (e.g. unsigned int)
  2. security should be held in a datatype that can hold very large numbers, e.g. unsigned long long
  3. Docs for the std::string constructors used

Upvotes: 1

kemis
kemis

Reputation: 4624

Why not create a new class with name,ID, password... and just override the ">>" operator?

and to creat the "xxxxxxxxxx" use the string constructor :

string word(oldword.size(), 'x'); 

oldword.size() is how long the word is , and 'x' is the character that will fill the whole string

Upvotes: 2

Related Questions