Câu trả lời ngắn
Vấn đề nằm ở chỗ dot.exe
. GraphViz có thể mở các tệp có đường dẫn Unicode trong Linux nhưng không phải Windows, trừ khi (có thể) nếu được biên dịch với Visual Studio 2005.
Nghiên cứu
Trang mã được đặt thành 850
, mã hóa Vim thành UTF-8
.
Nó không đưa ra cùng một lỗi chính xác, nhưng dot.exe
dường như nhận được một đối số sai. Tôi đã thử chuyển cùng tên tệp cho chương trình khác.
Và nó hoạt động vừa phải. Thực thi cả hai dot.exe
và type
trực tiếp từ đều cmd.exe
cho cùng một kết quả, vì vậy cả Windows Console và Vim đều không thành vấn đề. Điều tiếp theo có thể gây ra lỗi đó là dot.exe
chính nó. Sự nghi ngờ của tôi là nó chỉ không biết cách xử lý các đối số được mã hóa Unicode đúng cách, vì thậm chí không phải tất cả các lệnh của bàn điều khiển đều làm:
https://ss64.com/nt/chcp.html
Nếu bạn cần hỗ trợ Unicode đầy đủ, hãy sử dụng PowerShell. Vẫn còn RẤT hỗ trợ hạn chế cho Unicode trong vỏ CMD, đường ống, chuyển hướng và hầu hết các lệnh vẫn chỉ là ANSI. Các lệnh duy nhất hoạt động là DIR, FOR / F và TYPE, điều này cho phép đọc và ghi các tệp và tên tệp (UTF-16LE / BOM) nhưng không phải là nhiều tên khác.
Tôi đã tìm kiếm trên web nếu có hỗ trợ Unicode trong GraphViz và thấy rằng nó hỗ trợ các tệp Unicode nhưng không có gì hỗ trợ Unicode cho tên tệp. Tôi cũng không tìm thấy bất kỳ báo cáo nào về trình theo dõi lỗi GraphViz cũng như các bài đăng trên diễn đàn về bất kỳ ai khác quan tâm đến việc đọc một tệp có tên Unicode. Vì vậy, tôi tìm nó trong nguồn. Ở đây dot.exe
điểm vào là gì :
graphviz-2.40.1\cmd\dot\dot.c
int main(int argc, char **argv)
{
. . .
/* --------------------> ARGS ARE BEING PASSED HERE */
gvParseArgs(Gvc, argc, argv);
. . .
Theo argv
lỗ thỏ xuống:graphviz-2.40.1\lib\common\args.c
int gvParseArgs(GVC_t *gvc, int argc, char** argv)
{
int rv;
if ((argc = neato_extra_args(gvc, argc, argv)) < 0) return (1-argc);
if ((argc = fdp_extra_args(gvc, argc, argv)) < 0) return (1-argc);
if ((argc = memtest_extra_args(gvc, argc, argv)) < 0) return (1-argc);
if ((argc = config_extra_args(gvc, argc, argv)) < 0) return (1-argc);
/* --------------------> HERE GO ALL NON-FLAG ARTUMENTS */
if ((rv = dotneato_args_initialize(gvc, argc, argv))) return rv;
if (Verbose) gvplugin_write_status(gvc);
return 0;
}
graphviz-2.40.1\lib\common\input.c
int dotneato_args_initialize(GVC_t * gvc, int argc, char **argv)
{
for (i = 1; i < argc; i++) {
if (argv[i] && argv[i][0] == '-') {
. . .
/* --------------------> JUST CASUALLY COPYING CHAR POINTERS */
} else if (argv[i])
gvc->input_filenames[nfiles++] = argv[i];
}
Và cuối cùng graphviz-2.40.1\lib\common\input.c
graph_t *gvNextInputGraph(GVC_t *gvc)
{
. . . .
/* --------------------> OPENING THE FILES FOR READ WITH FOPEN */
while ((fn = gvc->input_filenames[fidx++]) && !(fp = fopen(fn, "r"))) {
. . .
}
Như MDSN tuyên bố:
Hàm fopen mở tệp được chỉ định bởi tên tệp. _wfopen là phiên bản rộng của fopen ; các đối số cho _wfopen là các chuỗi ký tự rộng. _wfopen và fopen hành xử giống hệt nhau. Đơn giản chỉ cần sử dụng _wfopen không có tác dụng đối với bộ ký tự được mã hóa được sử dụng trong luồng tệp.
Trong Visual C ++ 2005, fopen hỗ trợ các luồng tệp Unicode.
Đáng buồn thay, lựa chọn duy nhất là đổi tên tập tin.
cmd
chấp nhận tên tệp, nhưng cài đặt môi trường giống Unix sẽ là cách xử lý ưa thích của riêng tôi.