2010-11-18 11 views
1

Ich habe eine Shell eines Programms gegeben und muss ein paar Funktionen ausfüllen.strncopy Kopieren mehr als n Zeichen

Ich habe zwei Strukturen, die ich bin, die automatisch erstellt und an die Funktionen übergeben werden, die ich definieren muss.

typedef struct { 
    char data[20]; 
} msg; 

typedef struct { 
    int seqnum; 
    int acknum; 
    int checksum; 
    char payload[20]; 
} pkt; 

sagen, dass ich diese Funktion foo definieren und haben sie als solche erstellt:

void foo(msg message) { 
    printf("%s\n", message.data); 
} 

Wenn diese Funktion aufgerufen wird, es ddddddddddddddddddddôÑ@<úHn½*Ìå«*¤ú¤F«* ausdruckt. Wenn ich nicht falsch bin, sollte es nicht nur 20 Zeichen enthalten? Ich erstelle nicht wirklich msg.

Es wird noch seltsamer, wenn ich msg.data zu pkt.payload kopiere.

void foo(msg message) { 
    pkt packet; 
    strncpy(packet.payload, message.data, sizeof(packet.payload)); 
    printf("%s\n", message.data); 
    printf("%s\n", packet.payload); 
} 

message.data druckt die gleiche wie zuvor, aber packet.payload druckt eeeeeeeeeeeeeeeeeeee<úeeeeeeeeeeeeeeeeeeee²[email protected]<úHn½*Ìå«*¤ú¤F«*. Warum sind es mehr als 20 Zeichen?

Das ist das erste Mal, dass ich C benutze, also vergib mir, wenn das offensichtlich ist, aber ich kann nicht einmal zum Kern der Aufgabe kommen, da ich Probleme mit der Sprache habe.

+0

Verwenden '% .20s' in Ihrem' printf' Format-String, wenn Sie es mit 20-Byte-Felder zu arbeiten, die nicht null-terminiert sein könnte. –

Antwort

2

printf(), mit einem% s-Spezifizierer, nimmt an, dass Sie eine Null-terminierte Zeichenfolge senden. So liest es Bytes im Speicher, bis es eine Null findet (oder '\0').

strncpy fügt keine Null an die Zielzeichenfolge an, es sei denn, in der Quellzeichenfolge wird eine Null gefunden, bevor n Zeichen erreicht sind (zu diesem Zeitpunkt wird der Rest der Zielzeichenfolge mit Nullen aufgefüllt) Null-terminiert).

+2

Genauer gesagt, 'strncpy' fügt keine Null an die Zielzeichenfolge an, wenn die Quellzeichenfolge n Zeichen oder länger ist. – Arkku

+0

@Arkku: In der Tat habe ich bearbeitet. –

2

strncpy beendet die zu kopierende Zeichenfolge nicht.

Sie müssen entweder auf das Feld manuell beenden,

strncpy(packet.payload, message.data, sizeof(packet.payload) - 1); 
packet.payload[sizeof(packet.payload) - 1] = '\0'; 
printf("%s\n", message.data); 
printf("%s\n", packet.payload); 

oder behandeln es als eine feste Größe potenziell ungekündigten string:

strncpy(packet.payload, message.data, sizeof(packet.payload)); 
printf("%s\n", message.data); 
printf("%.*s\n", sizeof packet.payload, packet.payload); 

Alternativ können Sie halten es mit snprintf beendet (C99), die weniger fehleranfällig ist, da sie immer die Zeichenfolge beendet.

snprintf(packet.payload, sizeof packet.payload, "%s", message.data); 
printf("%s\n", message.data); 
printf("%s\n", packet.payload); 
0
strncpy(packet.payload, message.data, sizeof(packet.payload)); 
packet.payload[sizeof(packet.payload) - 1] = 0;