stream manipulieren mit iomanip



  • hallo,

    problem konnte lokalisiert werden und es tritt beim manipulieren dieser zeichen auf:

    std::cout<<Parser("§")<<std::endl;
    
    std::cout<<Parser("Ä")<<std::endl;
    
    std::cout<<Parser("Ö")<<std::endl;
    

    probleme gibt es noch bei: Ü, ü, ä, ö, ², ³, ´

    einstellung für Character Set:
    Use Multi-Byte Character Set

    hab das dann weggeschalten...funzte aber auch nicht;-(
    auch wenn ich i in (unsigned char) caste nicht...

    i ist also wie ich merke >= 255...klar könnt ich das mit der If abfangen...
    aber will ja auch bei "´L" das erste zeichen manipulieren...

    cu



  • hier paar weitere infos:

    code

    std::cout<<Parser("§")<<std::endl;
    

    debug infos:

    _ctype.c
            if ( ptloci != __ptlocinfo )
                ptloci = __updatetlocinfo();
    
            return __isalnum_mt(ptloci, c);   <----error
    
    Call Stack
    Temp.exe!_chvalidator_mt(threadlocaleinfostruct * p=0x003231b8, int=-89, int mask=263) Line 68 + 0x2a
    Temp.exe!isalnum(int c=-89) Line 165 + 0x35
    

    cu



  • hmmmmmmmmm schrieb:

    warum nimm denn isalnum überhaupt ein integer als parameter?? warum nicht (unsigned?) char?

    Das wurde in diesem Forum schon ca. 1.7 Millionen mal erklärt. Genau wie die Tatsache, dass Code wie dieser:

    for(std::string::const_iterator i=s.begin();i!=s.end();i++) 
    { 
        if(std::isalnum(*i)) 
        ...
    }
    

    schlicht falsch ist.
    Die Suchfunktion hilft interessierten sicher weiter. Allen anderen bleiben langweilige Wiederholungen erspart 😉



  • ich bin nicht in der lage auch nur einen von den 1.7 millionen beiträgen zu finden 😞

    suche nach isalnum im c++ forum ergab ca. 10 treffer, wo aber überall nur die funktion verwendet wurde und nichts weiter dazu erklärt wird.



  • hmmmmmmmm schrieb:

    ich bin nicht in der lage auch nur einen von den 1.7 millionen beiträgen zu finden 😞

    suche nach isalnum im c++ forum ergab ca. 10 treffer, wo aber überall nur die funktion verwendet wurde und nichts weiter dazu erklärt wird.

    Jup. Erklärt wurde das Ganze bisher nur für andere "character classification"-Funktionen wie z.B. tolower oder toupper.
    Schau z.B. mal hier:
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-82570-and-start-is-30.html
    Dort musst du die letzte Seite auswählen. Und ganz wichtig, nicht vergessen den letzten Link anzuklicken.

    Das Prinzip ist immer das selbe.

    Zusammengefasst:
    1. die Funktionen erwarten einen int, da sie zwei Sorten von Eingaben verarbeiten können:
    a) alle Zeichen, die als *unsigned char* dargestellt werden können
    b) EOF
    Da nun EOF nicht gleichzeitig auch als ein gültiges Zeichen repräsentiert werden kann, muss ein Datentyp her, der mehr Werte als alle gültigen Zeichen aufnhemen kann -> int.

    2. Da die Funktionen ihre korrekt Funktionsweise nur unter a) und b) garantieren, muss der Aufrufer garantieren, dass sein Parameter a) oder b) erfüllt. Da char in C++ nun aber sowohl signed als auch unsigned char sein kann, ist die einzige Möglichkeit wie man a) garantieren kann die, dass man sein Zeichen nach unsigned char castet bevor man es an eine der Funktionen übergibt. Ansonsten ist das Verhalten für eine Platform auf der char == signed char gilt und für Zeichen die nicht im "basic execution character set" liegen undefinert. Und Zeichen wie 'ü' oder '§' sind nun mal nicht Teil des BECS.

    Richtig wäre also:

    for(std::string::const_iterator i=s.begin();i!=s.end();i++) 
    { 
        if(std::isalnum(static_cast<unsigned char>(*i))) 
        ...
    }
    


  • hi, danke das beantwortet schon viele fragen!!
    aber was mach ich nun mit ü und § usw?
    ps.: der hmmmmmmmm bin nicht ich!!
    cu



  • cplusplus. schrieb:

    aber was mach ich nun mit ü und § usw?

    Das kommt darauf an, was genau du erreichen willst. Erstmal musst diese Zeichen (wie oben beschrieben) nach unsigned char casten, bevor du sie an deine Klassifizierungsfunktion übergibst. Danach musst du dir über locales Gedanken machen. Das Standard-C-Lokale wird für isalnum(static_cast<unsigned char>('ü')) Null liefern, da 'ü' aus Sicht dieses locales kein alpha-numerisches Zeichen ist (das Englische-Alphabet enthält kein ü).
    Wenn du dich aber nicht auf das Englische-Alphabet beschränken willst, dann musst du ein passendes Locale installieren. Z.B. ein Deutsches. Wie genau das geht, musst du deinem Compiler-Handbuch entnehmen, da die Locale-Strings nicht standardisiert sind.
    Ein Beispiel:

    #include <ctype.h>
    #include <locale.h>
    #include <iostream>
    using namespace std;
    
    void check(const char* l)
    {
      cout << "ä ist laut " << l << " - locale ";
      if (isalnum(static_cast<unsigned char>('ä')) == 0)
        cout << "*kein*";
      else
        cout << "*ein*";
      cout << " alpha-numerisches Zeichen!" << endl;
    }
    int main()
    {
      const char* old = setlocale(LC_CTYPE, 0);
      check(old);
      if (const char* newLoc = setlocale(LC_CTYPE, "german"))
      {
        check(newLoc);
      }
      setlocale(LC_CTYPE, old);
    
    }
    


  • will diese codierung machen:
    ö -> %F6
    ä -> %E4
    ü -> %FC
    Ö -> %D6
    Ä -> %C4
    Ü -> %DC
    § -> %A7

    Z.B. ein Deutsches. Wie genau das geht, musst du deinem Compiler-Handbuch entnehmen, da die Locale-Strings nicht standardisiert sind.

    ok gut, da ich visual studio 2003 .net habe werd ich mal google befragen...

    also bei visual studio 2003 .net kann ich folgende einstellung machen:
    Character Set:
    - Not Set
    - Use Unicode Character Set
    - Use Multi-Byte Character Set

    was ist da der unterschied...mir sagt nur unicode was...
    cu



  • hi, hab das mit setlocale probiert und hier meine infos entnommen:
    http://cplus.kompf.de/artikel/locale.html
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt_language_and_country_strings.asp

    aber ich bring das nicht zum laufen;-(

    cu



  • hi,
    ich hab genommen:

    setlocale(LC_CTYPE, "de_DE");
    

    ich brauch

    <<(int)*i;
    

    denn '#' -> %23

    wie kann ich das schöner machen?

    if(*i == 'ä')
          o<<"%E4";
        else if(*i == 'ö')
          o<<"%D6";
        else if(*i == 'ü')
          o<<"%FC";
        else if(*i == 'Ä')
          o<<"%C4";
        else if(*i == 'Ö')
          o<<"%D6";
        else if(*i == 'Ü')
          o<<"%DC";
        else if(*i == '§')
          o<<"%A7";
    	else if(std::isalnum(*i))
    	  o<<*i; 
    	else
    	  o<<'%'<<std::hex<<std::setw(2)<<std::setfill('0')<<(int)*i;
          }
    

Anmelden zum Antworten