Ich glaub ich habe da so ein bisschen was gefunden, da ich in Sachen Kodierung und Zeichensätze noch sehr frisch dran bin, korrigiert mich bitte, wenn ich falsch liege:
Der Unterschied ist doch, dass verschiedene Datentypen dem Stream übergeben werden.
Bei dem funktionierenden Beispiel ist es ein const char [], bei dem nicht-funktionierenden ein string.
Ein char sollte bei dir mit der Latin-1 Codepage kodiert sein (1 Byte), also sollte auch problemlos die Umlaute darstellen was ja auch funktioniert.
Ein string speichert ja wie gesagt die Bytes die du reingibst unabhängig von der Kodierung. Ich nehme nun an, dass du die Umlaute UTF-8 kodiert in den string schreibst.
Da ein Umlaut in UTF-8 2 Bytes zur Darstellung braucht, werden für die Umlaute auch 2 Bytes gespeichert.
Deine Ausgabe hat von der Kodierung keine Ahnung, sie ist aus dem String ja auch nicht ersichtlich, es ist Interpretationssache was man damit jetzt anstellt.
Die Ausgabe liest also Byte für Byte, in der Annahme jeder würde einem Zeichen entsprechen (ein Iterator über dem string würde auch nur Byte für Byte, statt char für char gehen, aus bereits erwähnten Gründen).
Somit erhältst du statt einem Umlaut 2 Zeichen, welche nicht viel mit diesem zu tun haben.
Ich habe das schon überprüft, die Ausgabe die du beschrieben hast dürfte passen. Die 2 Bytes die das Ä in UTF-8 braucht, habe ich in der Latin-1 Tabelle nachgeschlagen und tatsächlich ist das erste ein A mit Welle und das zweite ein nicht belegter Platz, da Vierecke sonst nicht vorkommen, würde auch das passen.
Was kann man dagegen tun? Ich weiß nicht inwiefern du deinem Log sagen kannst, welche Kodierung er zu erwarten hat. Oder du wandelst das gelesene in einen ISO 8859-1 konformen String um.
Wie das genau funktioniert weiß ich nicht, aber eine Umwandlung in einen 32-bit Unicode string, mit anschließendem Verwerfen der höherwertigen Code-Points sollte funktionieren.
Das war das was ich mit ein bisschen Recherche herausfinden konnte, ich hoffe ich liege richtig und konnte helfen.
mfg