Ich denke, die Codierung von (eine Kopie von) str
zu "unknown"
vor der Verwendung cat()
ist weniger Magie und funktioniert genauso gut. Ich denke, das sollte unerwünschte Zeichensatzkonvertierungen in cat()
vermeiden. Hier
ist ein erweitertes Beispiel zu zeigen, was ich denke, im ursprünglichen Beispiel passiert:
print_info <- function(x) {
print(x)
print(Encoding(x))
str(x)
print(charToRaw(x))
}
cat("(1) Original string (UTF-8)\n")
str <- "\xe1\xbb\x8f"
Encoding(str) <- "UTF-8"
print_info(str)
cat(str, file="no-iconv")
cat("\n(2) Conversion to UTF-8, wrong input encoding (latin1)\n")
## from = "" is conversion from current locale, forcing "latin1" here
str2 <- iconv(str, from="latin1", to="UTF-8")
print_info(str2)
cat(str2, file="yes-iconv")
cat("\n(3) Converting (2) explicitly to latin1\n")
str3 <- iconv(str2, from="UTF-8", to="latin1")
print_info(str3)
cat(str3, file="latin")
cat("\n(4) Setting encoding of (1) to \"unknown\"\n")
str4 <- str
Encoding(str4) <- "unknown"
print_info(str4)
cat(str4, file="unknown")
In einem "Latin-1"
locale (siehe ?l10n_info
), wie von R auf Windows verwendet, Ausgabedateien "yes-iconv"
, "latin"
und "unknown"
sollte korrekt sein (Bytefolge 0xe1
, 0xbb
, 0x8f
das ist "ỏ"
).
In einem Gebietsschema "UTF-8"
sollten die Dateien "no-iconv"
und "unknown"
korrekt sein.
Die Ausgabe des Beispielcodes ist wie folgt, R 3.3.2 64-Bit-Windows-Version mit auf Wine ausgeführt wird:
(1) Original string (UTF-8)
[1] "ỏ"
[1] "UTF-8"
chr "<U+1ECF>""| __truncated__
[1] e1 bb 8f
(2) Conversion to UTF-8, wrong input encoding (latin1)
[1] "á»\u008f"
[1] "UTF-8"
chr "á»\u008f"
[1] c3 a1 c2 bb c2 8f
(3) Converting (2) explicitly to latin1
[1] "á»"
[1] "latin1"
chr "á»"
[1] e1 bb 8f
(4) Setting encoding of (1) to "unknown"
[1] "á»"
[1] "unknown"
chr "á»"
[1] e1 bb 8f
Im ursprünglichen Beispiel iconv()
den Standard from = ""
Argument verwendet, die Umwandlungsmittel aus das aktuelle Gebietsschema, das effektiv "latin1" ist. Da die Codierung von str
eigentlich "UTF-8" ist, wird die Byte-Darstellung der Zeichenfolge in Schritt (2) verzerrt, aber dann implizit durch cat()
wiederhergestellt, wenn sie (vermutlich) die Zeichenfolge zurück in das aktuelle Gebietsschema konvertiert, wie in die äquivalente Umwandlung in Schritt (3).
Ich kenne oder benutze R nicht selbst, aber wenn ich nur die Dokumentation lese, gibt 'cat() 'Zeichenketten" so wie sie sind "aus, und der' mark' Parameter von 'iconv()' ist standardmäßig true Aufrufen von 'iconv (str, to =" UTF-8 ")' markiert seine Ausgabe explizit als UTF-8, bevor es an 'cat()' übergeben wird. Vielleicht markiert 'str <-" ỏ "' nicht gleich "str"? Sie können 'enc2utf8 (str)' oder 'Encoding (str) <-" UTF-8 "' verwenden, um 'str' als UTF-8 explizit zu konvertieren und zu markieren, ohne' iconv() 'zu verwenden. Das macht wahrscheinlich einen Unterschied für 'cat()'. –