Falsche Codierung beim Aufrufen der Shell

9

Ich habe mit einem DOT-Diagramm experimentiert und versucht, Folgendes zu tun:

:! dot -Tpng -oFab.png %

Ich habe eine Fehlermeldung erhalten, weil mein Dateiname ein Sonderzeichen hat (" ó" in "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...

Wie Sie sehen können, wird das Sonderzeichen für " ├│" geändert . Dies ist mit vim und gVim 7.4 unter Win7 und NTFS, daher gehe ich davon aus, dass der Dateiname in UTF16 ist . Ich gehe auch davon aus, dass beim Aufrufen der Shell / cmd der Dateiname als eine andere Codierung interpretiert wird (danke an Carpetsmoker für den Hinweis, dass standardmäßig Codepage 850 verwendet wird ).

Wie kann ich das beheben?

Natürlich kann ich die Datei einfach umbenennen, aber ich möchte wissen, warum dies passiert und wie ich es korrigieren kann.

Update : Ich habe diese Frage gerade in superuser.SE gefunden (dank des Feedbacks von @ ChristianBrabandt ), aber es scheint auch nicht zu helfen.

Roflo
quelle
1
Ich bin gespannt, ob Sie mit Vim in der Befehlszeile unter Cygwin oder MobaXterm (tragbare Unix-ähnliche Umgebungen für Windows) denselben Fehler erhalten würden. Ich vermute nicht. Möglicherweise gibt es eine Möglichkeit, dies tatsächlich zu beheben, sodass Windows cmdden Dateinamen akzeptiert. Die Installation einer Unix-ähnlichen Umgebung wäre jedoch meine bevorzugte Vorgehensweise.
Wildcard
2
Nach dem, was ich gelesen habe, ist die Standardeinstellung für cmd.exenicht Unicode, sondern Codepage 850 . Siehe auch diese Antwort .
Martin Tournoij
Danke @Carpetsmoker. Ich habe mir erlaubt, meine Frage mit den von Ihnen angegebenen Informationen zu aktualisieren.
Roflo
Ich bin mir nicht ganz sicher, aber vielleicht möchten Sie die Option "Termencoding" optimieren.
Christian Brabandt
@ChristianBrabandt Wenn ich nichts falsch mache, scheint das nicht zu helfen. Ich habe versucht, tenc auf latin1, utf8 und cp850 zu setzen. Keiner scheint den Trick zu tun.
Roflo

Antworten:

2

Kurze Antwort

Das Problem liegt in dot.exe. GraphViz kann Dateien mit Unicode-Pfaden unter Linux öffnen, jedoch nicht unter Windows, es sei denn (möglicherweise), wenn es mit Visual Studio 2005 kompiliert wurde.

Forschung

Die Codepage ist auf 850Vim-Codierung eingestellt UTF-8.

Geben Sie hier die Bildbeschreibung ein

Es gibt nicht genau den gleichen Fehler, aber der dot.exescheint ein falsches Argument zu erhalten. Ich habe versucht, den gleichen Dateinamen an das andere Programm zu übergeben.

Geben Sie hier die Bildbeschreibung ein

Und es hat genau richtig funktioniert. Das Ausführen von beiden dot.exeund typedirekt von cmd.exeführt zu demselben Ergebnis, sodass weder die Windows-Konsole noch Vim das Problem sind. Das nächste, was diesen Fehler verursachen konnte, war sich dot.exeselbst. Mein Verdacht war, dass es einfach nicht weiß, wie man mit den Unicode-codierten Argumenten richtig umgeht, wie es nicht einmal alle Konsolenbefehle tun:

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

Wenn Sie vollständige Unicode-Unterstützung benötigen, verwenden Sie PowerShell. Es gibt immer noch SEHR eingeschränkte Unterstützung für Unicode in der CMD-Shell, Piping, Umleitung und die meisten Befehle sind immer noch nur ANSI. Die einzigen Befehle, die funktionieren, sind DIR, FOR / F und TYPE. Dies ermöglicht das Lesen und Schreiben von (UTF-16LE / BOM) Dateien und Dateinamen, aber sonst nicht viel.

Ich habe im Web gesucht, ob Unicode in GraphViz unterstützt wird, und festgestellt, dass es Unicode- Dateien unterstützt, aber nichts über die Unicode-Unterstützung für die Dateinamen. Weder habe ich Berichte über den GraphViz-Bug-Tracker noch Beiträge im Forum über andere Personen gefunden, die daran interessiert sind, eine Unicode-Datei mit dem Namen zu lesen. Also habe ich es in der Quelle nachgeschlagen. Hier dot.exesieht der Einstiegspunkt aus:

graphviz-2.40.1\cmd\dot\dot.c

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

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

    . . .

Folgen argvSie dem Kaninchenbau: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];
    }

Und schließlich 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")))  {

        . . .

    }

Wie der MDSN feststellt:

Die Funktion fopen öffnet die durch den Dateinamen angegebene Datei. _wfopen ist eine Version von fopen mit breiten Zeichen . Die Argumente für _wfopen sind Zeichenfolgen mit breiten Zeichen. _wfopen und fopen verhalten sich ansonsten identisch. Die einfache Verwendung von _wfopen hat keine Auswirkung auf den im Dateistream verwendeten codierten Zeichensatz.

In Visual C ++ 2005 unterstützt fopen Unicode-Dateistreams.

Leider besteht die einzige Möglichkeit darin, die Datei umzubenennen.


quelle