Alternativen zur replace Funktion



  • Hallo, ich suche nun schon etwas länger um herauszufinden wie ich die

    std::replace( s.begin(), s.end(), 'x', 'y');
    

    -Funktion mit
    Strings zu benutzen kann.

    Also so:

    string a = "Hallo";
    string b = "Bye";
    
    std::replace( s.begin(), s.end(), a, b);
    

    Und die find funktion möchte ich nicht nutzen, da ich in einem Text alles auf einmal ersetzten möchte und wenn dieser String/Buchstabe nicht gefunden wurde
    schmiert es ab!

    Hier ist die Fehlermeldung die ich bekomme wenn ich replace mit strings benutze:

    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1311): error C2678: Binärer Operator '==': Es konnte kein Operator gefunden werden, der einen linksseitigen Operanden vom Typ 'char' akzeptiert (oder keine geeignete Konvertierung möglich)
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(470): kann 'bool std::operator ==(const std::_Exception_ptr &,const std::_Exception_ptr &)' sein
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(475): oder "bool std::operator ==(std::_Null_type,const std::_Exception_ptr &)"
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\exception(481): oder "bool std::operator ==(const std::_Exception_ptr &,std::_Null_type)"
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\system_error(408): oder "bool std::operator ==(const std::error_code &,const std::error_condition &)"
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\system_error(416): oder "bool std::operator ==(const std::error_condition &,const std::error_code &)"
    1>          bei Anpassung der Argumentliste '(char, const std::string)'
    1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1322): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void std::_Replace<char*,_Ty>(_FwdIt,_FwdIt,const _Ty &,const _Ty &)".
    1>          with
    1>          [
    1>              _Ty=std::string,
    1>              _FwdIt=char *
    1>          ]
    1>          c:\users\jan\documents\visual studio 2010\projects\easyencrypt\easyencrypt\main.cpp(22): Siehe Verweis auf die Instanziierung der gerade kompilierten Funktions-template "void std::replace<std::_String_iterator<_Elem,_Traits,_Alloc>,std::string>(_FwdIt,_FwdIt,const _Ty &,const _Ty &)".
    1>          with
    1>          [
    1>              _Elem=char,
    1>              _Traits=std::char_traits<char>,
    1>              _Alloc=std::allocator<char>,
    1>              _FwdIt=std::_String_iterator<char,std::char_traits<char>,std::allocator<char>>,
    1>              _Ty=std::string
    1>          ]
    1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm(1312): error C2440: '=': 'const std::string' kann nicht in 'char' konvertiert werden
    1>          Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werden
    

    Danke im Voraus 🙂



  • Combum schrieb:

    Hallo, ich suche nun schon etwas länger um herauszufinden wie ich die std::replace -Funktion mit Strings zu benutzen kann.

    So wie du es dir vorstellst garnicht.

    #include <string>
    #include <regex>
    #include <iostream>
    
    int main()
    {
    	std::string s{ "Hallo, foo bar! ich sagte \"Hallo\"! Hoerst du?? Hallo!!\n" };
    
    	std::cout << s;
    
    	std::regex  a{ "Hallo" };
    	std::string b{ "Bye" };
    
    	s = std::regex_replace( s, a, b );
    	std::cout << s;
    }
    


  • Hallo Combum,

    statt der allgemeinen replace-Funktion kannst du die string.replace-Funktion (zusammen mit string.find) benutzen, s.a. Replace substring with another substring C++

    Edit: der Link dort auf Replace part of a string with another string zeigt die m.E. beste Lösung für replaceAll.



  • Danke Swordfish,

    doch genau so stelle ich es mir vor! Stürzt sogar nicht ab wenn es einen Eintrag nicht gibt, Danke! 😃 👍
    Nur die geschweiften Klammern funzen bei mir nicht, normale runde aber. ()

    Th69:

    Danke dir für deine Antwort aber den meisten Code verstehe ich nicht,
    ich möchte nur das benutzen was ich auch gut verstehe.
    Und die Find Funktion löst eine Exception aus, wenn es einen Buchstaben nicht gibt,
    für mein kleines Programm nicht optimal.

    Danke für die schnellen Antworten! 👍



  • Combum schrieb:

    Und die Find Funktion löst eine Exception aus, wenn es einen Buchstaben nicht gibt, [...]

    Dann machst du damit Unsinn. Zeig Code.



  • Kann nicht, den code habe ich gestern schon verworfen. es funzt ja jetzt.
    Mit dem rest komme ich allein klar, aber als anfänger muss man sich auch mal selber davorhängen und rätseln 😉

    Grüße



  • Hallo, ich bins nochmal,
    Dieser QC soll eigentlich Texte wie: abcdefghijk
    in einen anderen zufälligen Text wie HbAkLopweRT "übersetzt" werden.
    In der Praxis werden aber verschiedene Buchstaben mit zwei gleichen übersetzt.
    Wie kommt das? Probiert den QC selber mal aus und gebt: abcdefghijklm ein.
    Dann sollte eigentlich jeder Buchstabe einen anderen zugewiesen bekommen.

    #include <string>
    #include <regex>
    #include <cmath> 
    #include <ctime>
    
    std::string text;
    
    std::regex  a( "a" );
    std::regex  aa( "A" );
    std::regex  b( "b" );
    std::regex  bb( "B" );
    std::regex  c( "c" );
    std::regex  cc( "C" );
    std::regex  d( "d" );
    std::regex  dd( "D" );
    std::regex  e( "e" );
    std::regex  ee( "E" );
    std::regex  f( "f" );
    std::regex  ff( "F" );
    std::regex  g( "g" );
    std::regex  gg( "G" );
    std::regex  h( "h" );
    std::regex  hh( "H" );
    std::regex  i( "i" );
    std::regex  ii( "I" );
    std::regex  j( "j" );
    std::regex  jj( "J" );
    std::regex  k( "k" );
    std::regex  kk( "K" );
    std::regex  l( "l" );
    std::regex  ll( "L" );
    std::regex  m( "m" );
    std::regex  mm( "M" );
    std::regex  n( "n" );
    std::regex  nn( "N" );
    std::regex  o( "o" );
    std::regex  oo( "O" );
    std::regex  p( "p" );
    std::regex  pp( "P" );
    std::regex  q( "q" );
    std::regex  qq( "Q" );
    std::regex  r( "r" );
    std::regex  rr( "R" );
    std::regex  s( "s" );
    std::regex  ss( "S" );
    std::regex  t( "t" );
    std::regex  tt( "T" );
    std::regex  u( "u" );
    std::regex  uu( "U" );
    std::regex  v( "v" );
    std::regex  vv( "V" );
    std::regex  w( "w" );
    std::regex  ww( "W" );
    std::regex  x( "x" );
    std::regex  xx( "X" );
    std::regex  y( "y" );
    std::regex  yy( "Y" );
    std::regex  z( "z" );
    std::regex  zz( "Z" );
    
    std::string alphabet[52] = { "a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z" };
    
    int main()
    {
    
    	//Eingabe von Text
    	std::cin >> text;
    
    	  srand(time(NULL));
    
              //zufälliges umstellen des arrays alphabet:
    	  random_shuffle(std::begin(alphabet), std::end(alphabet));
    
           //Ersetze a mit dem geshuffelten array alphabet[] in text.
    	text = std::regex_replace( text, a, alphabet[0] );
    	text = std::regex_replace( text, aa, alphabet[1] );
    	text = std::regex_replace( text, b, alphabet[2] );
    	text = std::regex_replace( text, bb, alphabet[3] );
    	text = std::regex_replace( text, c, alphabet[4] );
    	text = std::regex_replace( text, cc, alphabet[5] );
    	text = std::regex_replace( text, d, alphabet[6] );
    	text = std::regex_replace( text, dd, alphabet[7] );
    	text = std::regex_replace( text, e, alphabet[8] );
    	text = std::regex_replace( text, ee, alphabet[9] );
    	text = std::regex_replace( text, f, alphabet[10] );
    	text = std::regex_replace( text, ff, alphabet[11] );
    	text = std::regex_replace( text, g, alphabet[12] );
    	text = std::regex_replace( text, gg, alphabet[13] );
    	text = std::regex_replace( text, h, alphabet[14] );
    	text = std::regex_replace( text, hh, alphabet[15] );
    	text = std::regex_replace( text, i, alphabet[16] );
    	text = std::regex_replace( text, ii, alphabet[17] );
    	text = std::regex_replace( text, j, alphabet[18] );
    	text = std::regex_replace( text, jj, alphabet[19] );
    	text = std::regex_replace( text, k, alphabet[20] );
    	text = std::regex_replace( text, kk, alphabet[21] );
    	text = std::regex_replace( text, l, alphabet[22] );
    	text = std::regex_replace( text, ll, alphabet[23] );
    	text = std::regex_replace( text, m, alphabet[24] );
    	text = std::regex_replace( text, mm, alphabet[25] );
    	text = std::regex_replace( text, n, alphabet[26] );
    	text = std::regex_replace( text, nn, alphabet[27] );
    	text = std::regex_replace( text, o, alphabet[28] );
    	text = std::regex_replace( text, oo, alphabet[29] );
    	text = std::regex_replace( text, p, alphabet[30] );
    	text = std::regex_replace( text, pp, alphabet[31] );
    	text = std::regex_replace( text, q, alphabet[32] );
    	text = std::regex_replace( text, qq, alphabet[33] );
    	text = std::regex_replace( text, r, alphabet[34] );
    	text = std::regex_replace( text, rr, alphabet[35] );
    	text = std::regex_replace( text, s, alphabet[36] );
    	text = std::regex_replace( text, ss, alphabet[37] );
    	text = std::regex_replace( text, t, alphabet[38] );
    	text = std::regex_replace( text, tt, alphabet[39] );
    	text = std::regex_replace( text, u, alphabet[40] );
    	text = std::regex_replace( text, uu, alphabet[41] );
    	text = std::regex_replace( text, v, alphabet[42] );
    	text = std::regex_replace( text, vv, alphabet[43] );
    	text = std::regex_replace( text, w, alphabet[44] );
    	text = std::regex_replace( text, ww, alphabet[45] );
    	text = std::regex_replace( text, x, alphabet[46] );
    	text = std::regex_replace( text, xx, alphabet[47] );
    	text = std::regex_replace( text, y, alphabet[48] );
    	text = std::regex_replace( text, yy, alphabet[49] );
    	text = std::regex_replace( text, z, alphabet[50] );
    	text = std::regex_replace( text, zz, alphabet[51] );
    
    	//gebe den text wieder aus
    
    	std::cout << text << std::endl;
    
    	system("pause");
    	return 0;
    
    }
    

    Danke für eure Hilfe. 🙂



  • Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum MFC (Visual C++) in das Forum C++ (auch C++0x und C++11) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Combum schrieb:

    Hallo, ich bins nochmal,
    Dieser QC soll eigentlich Texte wie: abcdefghijk
    in einen anderen zufälligen Text wie HbAkLopweRT "übersetzt" werden.
    In der Praxis werden aber verschiedene Buchstaben mit zwei gleichen übersetzt.

    Logisch.

    Mach den
    http://de.wikipedia.org/wiki/Schreibtischtest
    und Dir wird's klar.



  • Combum schrieb:

    /* ... */
    

    face->hit( desk );

    #include <cctype>
    #include <chrono>
    #include <random>
    #include <array>
    #include <string>
    #include <iostream>
    
    int main()
    {
    	std::mt19937 engine{ static_cast< long unsigned >(
    		std::chrono::high_resolution_clock::now().time_since_epoch().count() ) };
    
    	std::array< char, 'z' - 'a' + 'Z' - 'A' + 2 > alphabet;	
    	for( std::size_t i{}; i < alphabet.size(); ++i )  // <<-- volkard-Gedaechtnis-Zeile.
    		alphabet[ i ] = ( i > 'z' - 'a' ? 'A' : 'a' ) + i % ( 'z' - 'a' + 1 );
    
    	std::shuffle( alphabet.begin(), alphabet.end(), engine );
    
    	std::string input;
    	std::cin >> input;
    
    	for( auto & ch : input )
    		if( std::isalpha( ch ) )
    			ch = alphabet[ ( std::islower( ch ) ? ch - 'a' : 'z' - 'a' + ch - 'A' + 1 ) ];
    
    	std::cout << input << '\n';
    }
    


  • Kein Grund, Loops zu verwenden!

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <random>
    #include <boost/range/irange.hpp>
    #include <boost/range/algorithm.hpp>
    #include <boost/range/join.hpp>
    #include <array>
    
    int main() {  
      std::array<char, 2*('z'-'a'+1)> from, to;
      boost::copy(boost::join(boost::irange('a', static_cast<char>('z'+1)), 
                              boost::irange('A', static_cast<char>('Z'+1))), from.begin());
      to = from;
      std::shuffle(begin(to), end(to), std::mt19937(std::random_device()()));
      std::transform(std::istreambuf_iterator<char>(std::cin), {},
                     std::ostreambuf_iterator<char>(std::cout),
                     [&](char c) { auto i = std::find(from.begin(), from.end(), c);
                                   return i==from.end() ? c : to[i-from.begin()]; });
    }
    


  • Kann mir denn mal jemand erklären wo ich den Fehler gemacht habe?
    Irgendwie sollte mir dieser Fehler peinlich sein, oder? 😕

    Ps: Solche krassen Algorithmen von Swordfish verstehe ich (noch) nicht.



  • volkard schrieb:

    Mach den Schreibtischtest.

    Schon versucht?



  • Ich wüsste nicht wie ich den machen sollte.
    Der Code ist ja ziemlich unkompliziert.
    Sind ja noch nicht einmal Zahlen dabei.

    Ich könnte mir aber vorstellen, dass bei dem Array was falsch ist? 😕



  • Combum schrieb:

    Ich wüsste nicht wie ich den machen sollte.

    Du sollst deinen Code mit einer Plausiblen eingabe mit Bleistift auf Papier durchgehen und dir ansehen, was Schritt für Schritt mit der Eingabe passiert.



  • ICH HABS!

    Wenn z.B. aus einem a ein C gemacht wurde wird später aus einem großen C wieder etwas anderes!

    Ab heute werde ich diesen neuartigen "Schreibtischtest" weiterempfehlen! 👍 😃

    Nächste Frage: Wie kann ich das am besten vermeiden?

    Noch eine Frage: Ich habe erst letztens bemerkt, dass cin nur bis zu einem Leerzeichen einliest, welche eingabemethode wäre am besten für einen kompletten text mit zeilenumbruch und allem?



  • iocc schrieb:

    Kein Grund, Loops zu verwenden!

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <random>
    #include <boost/range/irange.hpp>
    #include <boost/range/algorithm.hpp>
    #include <boost/range/join.hpp>
    #include <array>
    
    int main() {  
      std::array<char, 2*('z'-'a'+1)> from, to;
      boost::copy(boost::join(boost::irange('a', static_cast<char>('z'+1)), 
                              boost::irange('A', static_cast<char>('Z'+1))), from.begin());
      to = from;
      std::shuffle(begin(to), end(to), std::mt19937(std::random_device()()));
      std::transform(std::istreambuf_iterator<char>(std::cin), {},
                     std::ostreambuf_iterator<char>(std::cout),
                     [&](char c) { auto i = std::find(from.begin(), from.end(), c);
                                   return i==from.end() ? c : to[i-from.begin()]; });
    }
    

    🤡



  • Tut mir leid Ethon ich verstehe den QC nicht. kannst du eventuell auskommentieren,
    und mir die Zeilen angeben, die ich brauche, damit der Fehler nicht passiert? Außerdem bitte noch sagen an welche Stelle das gehört. Danke! 🙄



  • Combum schrieb:

    Nächste Frage: Wie kann ich das am besten vermeiden?

    Deine ganze Herangehensweise ist daneben. Dafür braucht man keine Regular Expressions ...

    Vorschlag:

    • Alphabet ( 'a' - 'z' , 'A' - 'Z' ) in ein Array alphabet schreiben

    • alphabet kräftig durchmischen

    • Benutzereingabe nach input lesen

    • Für jedes Zeichen in input

    • Position des Zeichens in einem nicht durchgewürfelten alphabet berechnen

    • Zeichen mit dem Zeichen an berechneter Position von alphabet ersetzen

    • input ausgeben

    Combum schrieb:

    Noch eine Frage: Ich habe erst letztens bemerkt, dass cin nur bis zu einem Leerzeichen einliest, welche eingabemethode wäre am besten für einen kompletten text mit zeilenumbruch und allem?

    std::getline() ließt eine Zeile (bis '\n' ).



  • Da es noch nicht explizit erwähnt wurde: Sobald du alle Buchstaben einzeln in den Code schreibst, und sogar noch Gross-/Kleinschreibung und 2 nacheinander als Varianten, hast du etwas Grundlegendes im Programmieren nicht verstanden. Nämlich Codeduplikation zu vermeiden, indem man ähnlich aussehende Codestücke durch Abstraktion (Funktionen, Schleifen, ...) vereinheitlicht.


Anmelden zum Antworten