2013-02-02 9 views
6

Ich habe viele Funktionen, die eine Zeichenfolge als Argument erwarten, für die ich char* verwenden, aber alle meine Funktionen, die ein Byte-Array erwarten, verwenden Sie auch char*.Unterscheiden zwischen String und Byte-Array?

Das Problem ist, dass ich leicht den Fehler machen kann, ein Byte-Array in einer String-Funktion zu übergeben, die alle Arten von Überläufen verursacht, weil der Null-Terminator nicht gefunden werden kann.

Wie ist das normalerweise delt? Ich kann mir vorstellen, alle meine Byte-Array-Funktionen zu ändern, um eine uint8_t zu nehmen, und dann wird der Compiler vor signed -ness warnen, wenn ich eine Zeichenfolge übergebe. Oder was ist der richtige Ansatz hier?

+0

Erstellen Sie einen Wrapper für ein Byte-Array? –

+0

@VaughanHilts Ich sehe nicht, wie das mein Problem löst? – Muis

+0

Ein String * ist * ein Byte-Array. Da Sie keine Arrays in C übergeben können, sondern nur einen Zeiger auf das erste Element, müssen Sie normalerweise auch eine Größe übergeben. Überprüfen Sie einfach, ob das Array einen Nullwert enthält. Wenn dies der Fall ist, handelt es sich um eine "Zeichenfolge". Ansonsten ist es nicht. –

Antwort

1

Das Problem ist allgemeiner in C, als Sie denken. Da char* und char[] für Funktionsparameter äquivalent sind, ein solcher Parameter zu drei verschiedenen semantischen Konzepte beziehen:

  • ein Zeiger auf einen char Objekt (das ist die „offizielle“ Definition von Zeigertypen)
  • a char Array
  • ein String

in den meisten Fällen, in denen ist möglich, die mondern Schnittstellen im C-Standard für eine nicht typisierte void* Byte verwendet ar ray, und Sie sollten sich wahrscheinlich an diese Konvention halten und char* nur für Strings verwenden.

char[] selbst werden wahrscheinlich selten als solche verwendet; Ich kann mir nicht viele Anwendungsfälle vorstellen. Wenn Sie sie als Zahlen betrachten, sollten Sie die signed oder unsigned Variante verwenden, wenn Sie sie nur als Bitmuster unsigned char sehen, sollten Sie Ihre Wahl sein.

Wenn Sie wirklich ein Array als Funktionsparameter (char oder nicht) bedeuten, können Sie diese Tatsache für den ungeübten Leser Ihres Codes markieren, indem es klar hervorgeht:

void toto(size_t n, char A[const n]); 

Dies entspricht

void toto(size_t n, char *const A); 

aber macht Ihre Absicht klarer. Und in der Zukunft könnte es sogar Werkzeuge geben, die die Grenzen für Sie überprüfen.

2

Ich mache im Allgemeinen ein Array so etwas wie die folgenden

typedef struct { 
    unsigned char* data; 
    unsigned long length; 
    unsigned long max_length; 
} array_t; 

passieren array_t dann * um

und Array-Funktionen erstellen, die array_t nehmen *

void array_create(array_t* a, unsgined long length) // allocates memory, sets the max_length, zero length 

void array_add(array_t* a, unsigned char byte) // add a byte 

etc

+1

wäre wahrscheinlich besser zu verwenden 'size_t' anstelle von 'unsigned long' –

+0

yep, du hast Recht –

0

schreiben eine gemeinsame Struktur für die Verarbeitung von String und Bytes.

struct str_or_byte 
{ 
    int type; 
    union 
    { 
     char *buf; 
     char *str; 
    }pointer; 
    int buf_length; 
} 

Wenn type nicht Zeichenfolge dann Zugriff auf die pointer.buf nur bis buf_length. Ansonsten greife direkt auf pointer.str zu, ohne buf_length zu prüfen, und behalte es als nullterminierte Zeichenkette bei.

Oder halten Sie die Zeichenkette auch als Byte-Array, indem Sie nur die Länge betrachten, behalten Sie nicht den nullterminierten Charater für die Zeichenkette bei.

struct str_or_byte 
{ 
    char *buf; 
    int buf_length; 
} 

Und nicht String-Manualisierungsfunktionen verwenden, die Länge nicht berücksichtigen. Das heißt, verwenden strncpy, strncat, strncmp ... statt strcpy, strcat, strcmp ...

0

C mit Konvention. Hier sind die Regeln, die ich verwende (nach der Standard-Lib)

void foo(char* a_string); 

void bar(void* a_byte_array, size_t number_of_bytes_in_the_array); 

Dies ist leicht zu merken. Wenn Sie ein einzelnes char * ptr übergeben, muss es ein null-terminiertes char-Array sein.