2011-01-02 13 views
3

Python verwöhnte mich und versuchte, mich um C zu wickeln, jetzt ist ein Blutbad von dummen Fehlern. Das kann ich nicht ganz verstehen.Warum haben diese Variablen den Typ scheinbar geändert?

Ich wollte das C-Äquivalent von Python os.path.split, aber es gibt keine genaue Entsprechung. strsep sieht ähnlich aus, aber muss massiert werden, um einfach verwendet zu werden.

Als erstes habe ich meinen Pfadtyp definiert: eine Zeichenfolge mit gegebener Länge.

Dann schrieb ich etwas Code, der die eigentliche Massage tut, versucht, Nebenwirkungen zu vermeiden - nur um die Dinge narrensicher zu halten.

typedef struct { 
    t_path next; 
    t_path remainder; 
} t_path_next 

t_path_next path_walk_into(t_path path) { 
    t_path_next output; 

    t_path my_next, my_remainder = "/"; 
    strncpy(my_next, path, MAX_PATH_LEN); 

    strsep(&my_next, my_remainder); 

    output.remainder = my_remainder; 
    output.next = my_next; 
    return output; 
} 

GCC ist jedoch nicht beeindruckt.

[email protected]:~/blah$ gcc path.c -Wall 
path.c: In function ‘path_walk_into’: 
path.c:39: warning: passing argument 1 of ‘strsep’ from incompatible pointer type 
/usr/include/string.h:559: note: expected ‘char ** __restrict__’ but argument is of type ‘char (*)[200]’ 
path.c:41: error: incompatible types when assigning to type ‘t_path’ from type ‘char *’ 
path.c:42: error: incompatible types when assigning to type ‘t_path’ from type ‘char *’ 

ich von der Notiz bin ratlos - wie geht es char ** und char (*)[200] wirklich anders - aber der Fehler ist noch seltsamer. Ich möchte eine Variable zuweisen, die ich t_path in einem Feld vom Typ t_path deklariert habe, aber ich komme nicht dazu.

Warum ist das?


Für alle Interesse hier ist das richtig funktionierende Version der Funktion:

t_path_next path_walk_into(t_path path) { 
    t_path_next output; 
    t_path my_path, delim = "/"; 
    char* my_path_ptr = my_path;  
    strncpy(my_path, path, MAX_PATH_LEN); 

    strsep(&my_path_ptr, delim); //put a \0 on next slash and advance pointer there. 

    if (my_path_ptr == NULL) //no more slashes. 
     output.remainder[0] = 0; 
    else 
     strncpy(output.remainder, my_path_ptr, MAX_PATH_LEN); 
    strncpy(output.next, my_path, MAX_PATH_LEN); 

    return output; 
} 
+0

Ein Teil des Problems ist, dass in C, Arrays zu Zeigern in verschiedenen Situationen zerfallen. Wenn Sie versuchen, 'char *' anstelle von 'char [...] ', dann können Sie bessere Ergebnisse erzielen. Ich habe es jedoch nicht ausprobiert :) –

+5

Die Verwendung von 'typedef' mit einem Array-Typ ist eine sichere Formel oder macht jeden, der jemals Ihren Code liest, wütend und versucht herauszufinden, was WTF macht. Tu das einfach nicht. –

+0

Wenn der vorherige Kommentar Sie fragen ließ (es ließ mich wundern), hier ist [eine Erklärung] (http://stackoverflow.com/questions/4523497/typedef-fixed-length-array/4523537#4523537). Es sieht für mich nicht besonders stark aus (der Code wird immer noch korrekt funktionieren), aber es ist immer noch gültig. – badp

Antwort

4

Die Fehler: Sie können nicht direkt auf ein Array zuweisen, wie eine Zeichenfolge, in C. Sie müssen sich kopiere char durch char, oder rufe str (n) cpy auf, was es für dich tut.

+0

Ohhh. Duh. Ich hoffte, dass würde eine Zeigerzuweisung machen :) – badp

3
  • Für die Warnung: Sie sind wahrscheinlich bereits, dass Array bewusst Zeiger kann zerfallen. Das heißt zum Beispiel, was ein Array als Argument für eine Funktion akzeptiert, für die ein Zeiger erwartet wird. In Ihrem Fall haben Sie einen Zeiger auf ein Array: Es gibt keinen Grund dafür, dass ein solcher Zeiger in einen Zeiger umgewandelt wird.

    Für das Protokoll, sagt der C99-Standard (6.3.2.1/3):

    Außer, wenn es der Operand des sizeof-Operator ist oder der einstellige & Operator, oder ist ein Stringliteral verwendet, um ein Array zu initialisieren, ein Ausdruck, der Typ '' Array des Typs '' hat ist in einen Ausdruck mit dem Typ '' Zeiger auf den Typ '', die auf das Anfangselement von das Array-Objekt und ist nicht ein Wert.

    Sie sind im Rahmen eines unären &: keine Konvertierung für Sie.

  • Für den Fehler: Es wurde bereits beantwortet, aber Array-Zuweisung ist nicht direkt möglich. Möglicherweise möchten Sie strcpy oder strncpy verwenden.

+0

Danke dafür, also würde eine explizite Umwandlung ausreichen, um zum Zeiger zum Feld zu einem Zeiger zum Zeiger zu wechseln? – badp

+1

@badp: Nein. Strsep erwartet einen Zeiger auf einen Zeiger, damit er diesen (zweiten) Zeiger ändern kann. Ihre Variable my_next ist ein t_path, der ein Array und kein Pointer ist, also ist _is_ kein Pointer für strsep zu ändern! –

Verwandte Themen