Mã hóa sai trong khi gọi shell


9

Tôi đã thử nghiệm với sơ đồ DOT và cố gắng làm như sau:

:! dot -Tpng -oFab.png %

Tôi đã gặp lỗi vì tên tệp của tôi có một ký tự đặc biệt (" ó" trong "Fabricación"):

C:\windows\system32\cmd.exe /c ( dot -Tpng -oFab.png Fabricaci├│n.gv)
Error: dot: can't open Fabricaci├│n.gv
shell returned 2
Hit any key to close this window...

Như bạn có thể thấy, ký tự đặc biệt đang được thay đổi cho " ├│". Đây là với vim và gVim 7.4 trong Win7 và NTFS, vì vậy tôi giả sử tên tệp là UTF16 . Tôi cũng giả định rằng khi gọi shell / cmd, tên tệp đang được hiểu là một số mã hóa khác (cảm ơn Carpetsmoker đã chỉ ra nó mặc định cho mã trang 850 ).

Làm thế nào tôi có thể sửa lỗi này?

Chắc chắn, tôi chỉ có thể đổi tên tập tin, nhưng tôi muốn biết tại sao điều này xảy ra và làm thế nào để sửa nó.

Cập nhật : Tôi vừa tìm thấy câu hỏi này trong superuser.SE (nhờ phản hồi của @ ChristianBrabandt ), nhưng dường như nó cũng không giúp được gì.


1
Tôi tò mò liệu bạn có gặp lỗi tương tự khi sử dụng Vim trên dòng lệnh trong Cygwin hoặc MobaXterm (môi trường giống như Unix di động cho Windows). Tôi nghi ngờ là không. Có thể có một cách để thực sự khắc phục điều này để Windows cmdchấ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.
tự đại diện

2
Từ những gì tôi đọc được, mặc định cmd.exekhông phải là unicode, mà là mã trang 850 . Cũng xem câu trả lời này .
Martin Tournoij

Cảm ơn @Carpetsmoker. Tôi có quyền tự do cập nhật câu hỏi của mình với thông tin bạn cung cấp.
Roflo

Tôi không hoàn toàn chắc chắn, nhưng bạn có thể muốn điều chỉnh tùy chọn 'termencoding'.
Christian Brabandt

@ChristianBrabandt Trừ khi tôi làm sai, điều đó dường như không có ích. Tôi đã thử cài đặt tenc thành latin1, utf8 và cp850. Không ai có vẻ là để làm cho lừa.
Roflo

Câu trả lời:


2

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.

nhập mô tả hình ảnh ở đây

Nó không đưa ra cùng một lỗi chính xác, nhưng dot.exedườ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.

nhập mô tả hình ảnh ở đây

Và nó hoạt động vừa phải. Thực thi cả hai dot.exetypetrực tiếp từ đều cmd.execho 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.exechí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 argvlỗ 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. _wfopenfopen 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.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.