2016-06-05 12 views
1

Dies ist mein Eingabestring: Muhammad Ali 65445519 76 butterfly123C++: String Formatierung

Dies ist meine gewünschte Ausgabe: Muhammad Ali xxx-xx-xxx 76 xxxxxxxxx

Hinweis: Anders als die Sozialversicherungsnummer (65445519) alles kann in der Länge variieren, dh Name, UserID (76) und Passoword (Butterfly123).

Beispiel:

Kobe Bryant 34567890 548 56mamba

Ich habe es gegeben einen Versuch, aber ich habe eine feste Benutzer-ID der Länge 2. Kann jemand mit einer Lösung kommen, in dem die Benutzer-ID kann auch variieren? oder ein ganz neuer Ansatz? Ich möchte keine String-Streams verwenden, in denen Sie die Eingabe nacheinander übernehmen und dann die Zeichenfolge verarbeiten. Jedoch wird eine effektive und kurze String-Stream-Lösung geschätzt werden. Vielen Dank.

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; 
+1

Warum nicht 'cctype' und' isdigit ((unsigned char) s.at (i)) 'anstelle der langen Bedingung in' if' verwenden? – MikeCAT

+0

@MikeCAT Danke Mann, benutzt es. – Mohsin

Antwort

1

Sie müssen getline(cin,s); nicht wirklich nutzen, können Sie die Daten in einzelne Variablen lesen:

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; 

Einige Hinweise zu diesem Code:

  1. Sie können einen kleineren unsigned integer-Datentyp verwenden für ID (zB unsigned int)
  2. security sollte in einem Datentyp gehalten werden, der sehr große Zahlen aufnehmen kann, z unsigned long long
  3. Docs for the std::string constructors used
+0

Danke dies ist wahrscheinlich die einzige Möglichkeit, es zu tun, andere Möglichkeiten, die Sie möglicherweise einen Fehler auftreten. – Mohsin

1

Ja, Sie sollten einen anderen Ansatz versuchen.

Betrachten Sie die folgende Eingabe

Sam123456789 FarkenParker 221778833 46 foobar 

Ihr Ansatz am Ende wird "123456789" mit X-s ersetzt, die eindeutig falsch ist.

Der richtige Ansatz:

1) Teilen Sie die Zeichenfolge in Worte durch Leerzeichen getrennt. Verwenden Sie std::array<std::string, 4> oder std::vector<std::string>, was auch immer für Sie funktioniert.

2) Ersetzen Sie einfach das 2. und das 5. Wort entsprechend.

3) Dann kombinieren Sie alles zurück, in einer einzigen Zeichenfolge.

+0

Vielen Dank für den Hinweis auf den Fehler. Wenn Sie etwas anderes finden, lassen Sie es mich wissen, ich möchte keine Arrays, Vektoren oder Klassen verwenden. – Mohsin

2

Warum eine neue Klasse mit dem Namen, ID, Passwort nicht schaffen ... und überschreiben Sie einfach den ">>" Operator?

und die „xxxxxxxxxx“ verwenden, um den Zeichenfolgenkonstruktor creat:

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

oldword.size() ist, wie lange das Wort, und ‚x‘ ist das Zeichen, das die gesamte Zeichenfolge füllt

+0

@Mohsin können Sie eine Struktur erstellen, aber das ist wie eine Klasse: D Ich mag Klassen zu machen, weil Sie ihre Operatoren für alles überschreiben können und dann können Sie Funktionen aus der Standard Template Library auf ihnen wie sie ein Basistyp sind – kemis

+0

@MiloRadosavljevic die obige Antwort ist machbar, ich bin eine Frage lösen, es heißt nicht, Klassen zu verwenden, aber sowieso alle anderen Vorschläge angewendet. Danke – Mohsin

+0

@Mohsin Statt vieler "if" s kannst du vergleichen funciton http://www.cplusplus.com/reference/string/string/compare/ – kemis