Zählen von Zeichen klappt nicht so richtig

chatumao

Grünschnabel
Hallo, vielleicht hat hier ja jemand eine Idee oder ich überseh etwas furchtbar Offensichtliches.
Ich gebe einen string ein, der als Parameter string str an zaehle_zeichen über geben wird.
Die Werte werden dann in einem "multi-vector" gespeichert. Wann immer count_char>0 soll eine Ausgabe erfolgen, was er auch macht.


Code:
void zaehle_zeichen(string str){

        int count_char;
        for(unsigned char cha=32;cha<255;cha++){
            int vi=(int) cha-32;
            count_char = count(str.begin(), str.end(), cha);
            wort_vector[vi][0]=count_char;
            if(count_char>0)cout<<"count_character_in_string(): schreibe Wert "<<count_char<<" in wort_vector ["<<vi<<"][0] fuer "<<cha<<endl;
            }
}


Beispiel:
Eingabe:"Frohes Neues Jahr" (ohne Anführungsstriche)

Ausgabe:


count_character_in_string(): schreibe Wert 2 in wort_vector [0][0] fuer //Leerzeichen
count_character_in_string(): schreibe Wert 1 in wort_vector [38][0] fuer F
count_character_in_string(): schreibe Wert 1 in wort_vector [42][0] fuer J
count_character_in_string(): schreibe Wert 1 in wort_vector [46][0] fuer N
count_character_in_string(): schreibe Wert 1 in wort_vector [65][0] fuer a
count_character_in_string(): schreibe Wert 3 in wort_vector [69][0] fuer e
count_character_in_string(): schreibe Wert 2 in wort_vector [72][0] fuer h
count_character_in_string(): schreibe Wert 1 in wort_vector [79][0] fuer o
count_character_in_string(): schreibe Wert 2 in wort_vector [82][0] fuer r
count_character_in_string(): schreibe Wert 2 in wort_vector [83][0] fuer s
count_character_in_string(): schreibe Wert 1 in wort_vector [85][0] fuer u

Hier das Problem: Eingabe: "Überaschung"

Ausgabe:

count_character_in_string(): schreibe Wert 1 in wort_vector [65][0] fuer a
count_character_in_string(): schreibe Wert 1 in wort_vector [66][0] fuer b
count_character_in_string(): schreibe Wert 1 in wort_vector [67][0] fuer c
count_character_in_string(): schreibe Wert 1 in wort_vector [69][0] fuer e
count_character_in_string(): schreibe Wert 1 in wort_vector [71][0] fuer g
count_character_in_string(): schreibe Wert 1 in wort_vector [72][0] fuer h
count_character_in_string(): schreibe Wert 1 in wort_vector [78][0] fuer n
count_character_in_string(): schreibe Wert 1 in wort_vector [82][0] fuer r
count_character_in_string(): schreibe Wert 1 in wort_vector [83][0] fuer s
count_character_in_string(): schreibe Wert 1 in wort_vector [85][0] fuer u

Es fehlt das 'Ü', gleiches gilt auch für alle weiteren Zeichen auf der ASCII Tabelle jenseits des Tilde Zeichens.
Ein char speichert nur Werte bis 127 wenn signed, aber ich hab einen unsigned genommen und ich verstehs nicht.

Bin für jede Idee dankbar.
 
Hi.

Du gehst die Sache zu kompliziert an.

Geh doch einfach den String durch und zähle die Vorkommen in einem Array. Dabei würdest du nicht (255-32) * Länge_des_Strings Iterationen benötigen, sondern nur Länge_des_Strings Iterationen.
 
Danke, deepthroat, für die Antwort. Habe noch einmal von vorne mit einer anderen Vorgehensweise begonnen. Das hätte eh zu lange gedauert mit dem System oben, Laufzeit war ewig.

Aber warum er die nicht zählt würd mich schon interessieren, irgendeinen Grund muss das ja haben.

Trotzdem vielen Dank für den Tipp.
 
Aber warum er die nicht zählt würd mich schon interessieren, irgendeinen Grund muss das ja haben.
In einem string sind "char" gespeichert, keine "unsigned char".

Das heißt std::count führt folgenden Vergleich durch:
Code:
if (»char« == »unsigned char«)

Die Konvertierungsregeln von C / C++ besagen, dass bei arithmetischen Operationen zwischen integralen Typen, bei gleichem Rang beide Operanden zu "int" konvertiert werden. (es ist etwas komplizierter, siehe den C Standard)

Je nach Zeichensatz gibt das z.B. auf einer x86 Architektur folgendes Bild:
C:
char ue_c = 'Ü';
unsigned char ue_uc = 'Ü';

printf("%d <=> %d\n", (int)ue_c, (int)ue_uc);
Ausgabe:
Code:
-36 <=> 220
Wie man leicht sieht, sind die Werte ungleich.

Das kann verhindert werden indem man einen der Operanden explizit castet.
 
Ah so ist das... Mit casten hab ich noch nicht angefangen, werds aber im Hinterkopf behalten für den Fall das ichs mal brauchen werde. Danke für die Aufklärung!
 
Zurück