Tôi nghĩ rằng việc đặt Mã hóa (bản sao) str
thành "unknown"
trước khi sử dụng cat()
ít phép thuật hơn và cũng hoạt động tốt. Tôi nghĩ rằng nên tránh bất kỳ chuyển đổi tập hợp ký tự không mong muốn nào trong cat()
.
Dưới đây là một ví dụ mở rộng để chứng minh những gì tôi nghĩ rằng sẽ xảy ra trong ví dụ ban đầu:
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")
Trong một miền địa phương "Latin-1"
(xem ?l10n_info
) như được sử dụng bởi R trên Windows, các file đầu ra "yes-iconv"
, "latin"
và "unknown"
nên đúng (chuỗi byte 0xe1
, 0xbb
, 0x8f
là "ỏ"
).
Trong miền địa phương "UTF-8"
, tệp "no-iconv"
và "unknown"
phải chính xác.
Đầu ra của mã ví dụ như sau, sử dụng R 3.3.2 64-bit phiên bản Windows đang chạy trên Wine:
(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
Trong ví dụ ban đầu, iconv()
sử dụng from = ""
đối số mặc định có nghĩa là chuyển đổi từ miền địa phương hiện tại, có hiệu quả là "latin1". Bởi vì mã hóa của str
thực sự là "UTF-8", biểu diễn byte của chuỗi bị bóp méo ở bước (2), nhưng sau đó được khôi phục hoàn toàn bằng cat()
khi nó (có lẽ) chuyển chuỗi trở lại miền địa phương hiện tại, như được minh họa bằng chuyển đổi tương đương ở bước (3).
Tôi không biết hoặc sử dụng R, nhưng chỉ đọc tài liệu, 'cat()' xuất ra chuỗi ký tự "như là", và tham số 'mark' của' biểu tượngv() 'là đúng theo mặc định, vì vậy gọi 'iconv (str, to =" UTF-8 ")' đánh dấu rõ ràng đầu ra của nó là UTF-8 trước khi nó được chuyển tới 'cat()'. Có lẽ 'str <-" ỏ "' không đánh dấu 'str' theo cùng một cách? Bạn có thể sử dụng 'enc2utf8 (str)' hoặc 'Encoding (str) <-" UTF-8 "' để chuyển đổi rõ ràng và đánh dấu 'str' là UTF-8 mà không sử dụng' iconv() '. Điều đó có thể tạo ra sự khác biệt với 'cat()'. –