2016-04-09 6 views
-1

Ich versuche, eine Zeile aus einer Datei eingelesen und kopieren Sie die Daten in ein Zeichen-Array mit strcpy() Ich verstehe, dass strcpy() benötigt ein Null-Abschlusszeichen am Ende der Zeile andernfalls es wird seg Fehler, obwohl ich auch versucht habe mit einer bestimmten Puffergröße mit strncpy() sowie strncat() mit den gleichen Ergebnissen. In meinem Snippet habe ich versucht, einfach ein Null-Beendigungszeichen am Ende des Tokens hinzuzufügen.mit strcpy() mit strtok

Hier ist der Ausschnitt aus meinem Code, fehlgeschlagen war:

token = strtok(line, s); 
    strcpy(update, token); 
    token = strtok(NULL, s); 
    token = token + '\0'; 
    strcpy(firstName, token); 
    token = strtok(NULL, s); 

Der erste strcpy() Aufruf in dieser Funktion noch nicht ausgefallen ist. Das zweite Mal, dass ich strcpy() rufe, schlägt es jedes Mal fehl, wenn ich versuche, es auszuführen.

Der Rest meines Code kann here

+0

Was erwarten Sie mit der Anweisung 'token = token + '\ 0';'? Und wie sind 'update' und' firstName' definiert? – lurker

+0

Sie müssen zeigen, was 'update' ist. – John3136

+1

Ohne zu wissen, wie Update und Vorname definiert sind und/oder was sie zeigen, kann diese Frage nicht beantwortet werden. – Pemdas

Antwort

3

Sie müssen Nullzeiger vor dem Kopieren prüfen.

token = strtok(line, s); 
strcpy(update, token); 
token = strtok(NULL, s); 
//token = token + '\0'; 
if(NULL != token) 
{ 
    strcpy(firstName, token); 
    token = strtok(NULL, s); 
} 
+0

Ich habe nicht bemerkt, dass der letzte Wert, den meine Testdruckanweisung hatte, "NULL" war. Das Null-Beendigungszeichen war nicht das Problem, ich habe versucht, nichts nach 'firstName' zu ​​kopieren, indem ich' strcpy() 'benutzte, was den Segmentierungsfehler verursachte. Vielen Dank! – SuperNoobAttack

+0

@SuperNoobAttack: Wenn Sie sich die Mühe gemacht hätten, * meine Antwort * zu lesen, hätten Sie es früher gewusst: "Wenn der zweite strcpy fehlschlägt, liegt das wahrscheinlich daran, dass strtok fehlschlägt und einen Null-Zeiger zurückgibt." Und ich werde dafür abgelehnt. "Aber bin ich verbittert? Nein. Naja, vielleicht ein bisschen." –

0

strtok gibt entweder einen Null-Zeiger oder einen Zeiger auf einen NUL-termini Bytefolge (d.h. ein gültiger C string) gefunden werden.

Ihre token = token + '\0'; tut nicht, was Sie (fast sicher) denken. Seit token ist ein Zeiger (das ist der Rückgabetyp von strtok) es macht Zeigerarithmetik. Zum Glück '\0' ist eine langatmige Art zu sagen 0 (Trivia des Augenblicks: Zeichenliterale in C haben Typ int, nicht Typ char), so dass es zumindest den Zeiger nicht ändert.

Überprüfen Sie, ob der Wert von strtok zurückgegeben wird. Wenn Sie die zweite strcpy schlägt fehl, ist wahrscheinlich, weil strtok fehlschlägt und einen Nullzeiger zurückgibt.

Das heißt, vorausgesetzt, dass Sie eine einzige feste Zeichenfolge verwenden, um Ihre Begrenzer zu definieren, können Sie wahrscheinlich die Arbeit viel einfacher (und sauberer) mit sscanf. wenn s,.-+ enthalten zum Beispiel, könnten Sie verwenden:

sscanf(input, "%1[^,.-+]%*c%9[^,.-+]", update, firstname); 

ich den dritten Aufruf strtok jetzt ignoriert habe, weil Sie nie von seinem Rückgabewert zu einem Ziel zu kopieren (aber das Muster oben zu wiederholen wird natürlich für mehr Variablen arbeiten). Beachten Sie die Verwendung der Nummer zwischen % und dem Scan-Set ([^...]). Sie immer möchten die Größe des Puffers angeben, wenn Sie %s oder% [...] . The size you specify should always be one smaller than the buffer into which you're having them write (because they always append a trailing '\ 0'') verwenden.

auf gut Glück, dass s tatsächlich eine Zeichenfolge, die Sie von einer externen Quelle zu lesen ist (auf dieser Reihenfolge oder etwas, so dass Sie nicht leicht seinen Inhalt in einen Stringliteral setzen können) können Sie Ihr Formatstring zur Lauf synthetisieren Zeit, wenn nötig:

char template[] = "%%[^%s]%%*c%%[^%s]"; 
char format[512]; 

sprintf(format, template, s, s); 
sscanf(input, format, update, firstname); 

[Obwohl Formatstrings am häufigsten Literalen sind, ist das nicht erforderlich.]

Edit: ich glaube nicht, dass Sie ursprünglich den Code verknüpft würde, aber es zeigt zumindest ein Problem: char update[1];. Dies als Ziel von strcpy zu verwenden ist ein Problem, da es immer einen nachgestellten '\0' anfügt, um die Zeichenfolge zu beenden. In diesem Fall haben Sie nur ein einzelnes Zeichen zugewiesen, so dass Sie nur Platz für den Terminator und keine tatsächlichen Daten haben. Sie müssen es auf mindestens zwei Zeichen erweitern.Da Sie in Puffer mit fester Größe kopieren, möchten Sie wahrscheinlich vor dem Kopieren prüfen, ob die Zeichenfolge in den Puffer passt, oder aber etwas zum Kopieren verwenden, das die Größe der zu kopierenden Daten begrenzt (und immer noch enthält) ein Terminator, im Gegensatz zu strncpy).

+0

All dies und nicht einmal eine Erwähnung, dass wir nicht wissen, was "update" und "firstName" sind. Meine Wette ist nicht zugewiesen 'char *' – John3136

+0

@ John3136: Es ist * möglich *, und ja, es ist sogar nur gerade so möglich, dass die erste 'strcpy' Speicher verdirbt und zu dem Problem mit der zweiten führt. Aufgrund meiner Erfahrung ist dies jedoch nicht besonders wahrscheinlich die Quelle des Problems. Es könnte sicherlich sein, aber es könnte ebenso einfach ein fester Puffer sein, der zu kurz ist, uninitialisiert oder leer ist, so dass der erste Aufruf von strtok die gesamte Eingabe usw. verbraucht. –

+0

der Token = strtok (NULL , s); Diese Anweisung wurde verwendet, um zum nächsten Wert der Zeile zu gelangen, die ich in Token aufgeteilt habe. Ich habe jede dieser Aussagen getestet, indem ich sie ausgedruckt habe, und sie haben sich als die richtigen Werte erwiesen. – SuperNoobAttack