Неправильне кодування під час виклику оболонки


9

Я експериментував з DOT-діаграмою і намагався зробити наступне:

:! dot -Tpng -oFab.png %

Я отримав помилку, оскільки моє ім'я має спеціальний символ (" ó" у "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...

Як бачите, спеціальний символ змінюється на " ├│". Це з vim та gVim 7.4 під Win7 та NTFS, тому я припускаю, що ім'я файлу знаходиться в UTF16 . Я також припускаю, що при виклику оболонки / cmd ім'я файлу інтерпретується як якесь інше кодування (завдяки Carpetsmoker за те, що він вказав за замовчуванням на сторінку коду 850 ).

Як я можу це виправити?

Звичайно, я можу просто перейменувати файл, але хотілося б знати, чому це відбувається і як його виправити.

Оновлення : я щойно знайшов це питання в superuser.SE (завдяки відгуку @ ChristianBrabandt ), але, здається, це теж не допоможе.


1
Мені цікаво, якщо ви отримаєте ту саму помилку, використовуючи Vim у командному рядку під Cygwin або MobaXterm (переносні Unix-подібні середовища для Windows). Підозрюю, що ні. Можливо, є спосіб виправити це, щоб Windows cmdприйняла ім'я файлу, але встановлення подібного до Unix середовища було б моїм власним перевагою.
Wildcard

2
З того, що я прочитав, типовим для cmd.exeне є unicode, а сторінка коду 850 . Дивіться також цю відповідь .
Martin Tournoij

Дякуємо @Carpetsmoker. Я взяв на себе сміття оновити своє запитання з наданою вами інформацією.
Roflo

Я не зовсім впевнений, але ви, можливо, захочете налаштувати опцію 'termencoding'.
Крістіан Брабандт

@ChristianBrabandt Якщо я не роблю щось не так, це, здається, не допомагає. Я спробував встановити tenc на latin1, utf8 та cp850. Ніхто не здається зробити трюк.
Рофло

Відповіді:


2

Коротка відповідь

Проблема полягає в тому, що dot.exe. GraphViz може відкривати файли з контурами Unicode в Linux, але не в Windows, якщо (можливо), якщо вони компільовані з Visual Studio 2005.

Дослідження

На кодовій сторінці встановлено значення 850, на кодування Vim UTF-8.

введіть тут опис зображення

Це не дає точно такої ж помилки, але, dot.exeсхоже, отримує неправильний аргумент. Я спробував передати те саме ім’я файлу іншій програмі.

введіть тут опис зображення

І це справно працювало. Виконання dot.exeі typeбезпосередньо, і безпосередньо, cmd.exeдає однаковий результат, тому ні Консоль Windows, ні Vim не є проблемою. Наступне, що могло спричинити цю помилку, - це dot.exeсаме я. Я підозрював, що він просто не знає, як правильно керувати кодованими аргументами Unicode, як це не роблять навіть усі команди консолі:

https://ss64.com/nt/chcp.html

Якщо вам потрібна повна підтримка Unicode, використовуйте PowerShell. Є все ще ДУЖЕ обмежена підтримка Unicode в оболонці CMD, трубопровід, переадресація і більшість команд все ще є лише ANSI. Єдиними командами, які працюють, є DIR, FOR / F і TYPE, це дозволяє читати і записувати (UTF-16LE / BOM) файли та назви файлів, але не багато іншого.

Я шукав в Інтернеті, чи є підтримка Unicode у GraphViz, і виявив, що він підтримує файли Unicode, але нічого про підтримку Unicode для імен файлів. Ні я не знайшов жодних звітів про програму помилок GraphViz, ні публікацій на форумі про тих, хто цікавиться читати файл з іменем Unicode. Тому я подивився це в джерело. Ось як dot.exeвиглядає точка входу:

graphviz-2.40.1\cmd\dot\dot.c

int main(int argc, char **argv)
{
    . . .

/* --------------------> ARGS ARE BEING PASSED HERE */
    gvParseArgs(Gvc, argc, argv);

    . . .

Слідом за argvкролячим отвором: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];
    }

І остаточно 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")))  {

        . . .

    }

Як зазначає MDSN:

Функція fopen відкриває файл, вказаний ім'ям файлу. _wfopen - це широкоформатна версія fopen ; аргументи до _wfopen - це рядки з широкими символами. _wfopen та fopen ведуть себе однаково інакше. Просто використання _wfopen не впливає на кодований набір символів, який використовується у файловому потоці.

У Visual C ++ 2005, fopen підтримує потоки файлів Unicode.

На жаль, єдиний варіант - перейменувати файл.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.