2009-08-18 14 views
2

Ich bin neu in C und einige Quellcode überprüfen. Aber ich bin mir nicht sicher, was mit diesem Code-Snippet passiert.Zeichenfolgen und Zeiger

Ich glaube wirklich nicht, dass es irgendetwas tut, da im Debugging die Ausgabe für tempstr identisch zu sein scheint.

Das ist, was ich denke, richtig, wenn ich falsch liege. * (tempstr + strlen (line)) fügt die Länge der Zeile zu tempstr und Dereferenzierung und die Zuordnung der 0x0 konvertiert zu einem char?

char line[128], tempstr[128] 

strcpy(line, "AUTO_ANSWER_CALL = 1"); 
strcpy(tempstr,line); 
*(tempstr + strlen(line)) = (char) 0x0; // Confusing part 

Antwort

3

ist ein Zeiger-Wert:

tempstr 

Dies ist ein weiterer Zeigerwert (der auf 5 Elemente jenseits des tempstr Zeigerwert):

tempstr + 5 

Dies ist eine ganze Zahl:

strlen(line) 

Daher ist dies ein Zeigerwert (der auf strlen(line) Elemente jenseits derzeigtZeigerwert):

tempstr + strlen(line) 

Und das dereferencing diesen Zeiger:

*(tempstr + strlen(line)) 

Das ist, was ich denke, dann richtig, wenn ich falsch bin. * (tempstr + strlen (line)) fügt die Länge der Zeile zu tempstr und Dereferenzierung und die Zuordnung der 0x0 konvertiert zu einem char?

Es wird sichergestellt, dass der Charakter bei Index 20 von tempstr unmittelbar jenseits der „AUTO_ANSWER_CALL = 1“ Zeichen, null ist: das heißt, es ist sichergestellt, dass die Zeichenfolge nullterminierte ist.

Dieser String ist übrigens bereits null-terminiert (so dass die letzte Anweisung redudent ist): weil strcpy die Zeichenkette einschließlich des impliziten Null-Beendigungszeichens kopiert.


Ist das nicht einfacher, nur die folgende tempstr zu tun [sizeof (tempstr) -1] = '\ 0'; das ist viel einfacher zu verstehen.

Dies sind nicht die gleiche Sache: strlen(line) 20 ist gleich, aber sizeof(tempstr) gleich 128.


würde diese Arbeit: tempstr [strlen (tempstr)] = '\ 0'

das ist genau die gleichen Dinge wie:

*(tempstr + strlen(tempstr)) = '\0' 

Nur eine andere Art, es zu schreiben.

Wenn tempstr jedoch keine nullterminierte Zeichenfolge ist, wäre die Länge ebenfalls 128.

Wenn tempstr ist kein Null-terminierten String dann strlen(tempstr) nicht definiert ist (‚undefined‘ bedeutet, dass es sinnlos und gefährlich, um einen Fehler, und sollte nicht verwendet werden): die strlen Funktion außer nicht gültig ist, wenn es Wird für eine Zeichenfolge verwendet, die bereits nullterminiert ist.

+0

würde dies funktionieren: tempstr [strlen (tempstr)] = '\ 0'; Wenn tempstr jedoch NICHT eine nullterminierte Zeichenfolge ist, wäre die Länge ebenfalls 128. Weil ich die Länge einer unbestimmten Länge bekomme? Vielen Dank. – ant2009

+0

an meine Antwort angehängt – ChrisW

1

Ja, dieser Code ist null und beendet die Zeichenfolge.

+0

Ist nicht einfacher, nur die folgenden tempstr zu tun [sizeof (tempstr)] = '\ 0'; das ist viel einfacher zu verstehen. – ant2009

+0

Entschuldigung, das sollte sein: tempstr [sizeof (tempstr) -0] = '\ 0'; – ant2009

+0

Sorry, vielleicht zu viel hier zu hetzen sollte minus 1 statt Null gewesen sein. – ant2009

12

Zuerst, beachten Sie, dass der Code Mist ist.

*(tempstr + strlen(line)) = (char) 0x0; 

Es sieht aus wie der ursprüngliche Autor nicht ganz sicher war, ob strcpy das abschließende NUL-Zeichen kopiert, so dass er doppelt sicher gemacht anstatt das Handbuch des Prüfens (btw, strcpy tut das abschließende Null- kopieren).

Das ist im Grunde das gleiche wie:

tempstr[ strlen(line) ] = (char) 0; 

Die Besetzung zu char gibt es, glaube ich, wegen der Möglichkeit eines C++ Compiler verwendet wird, diesen Code zu kompilieren.

Ich bin nicht sicher, warum

char line[128] = "AUTO_ANSWER_CALL = 1"; 

nicht akzeptabel war.

+1

Vermutlich hat derjenige, der den Code ursprünglich geschrieben hat, gehört: char * line = "whatever"; 'hinterlässt eine nicht änderbare Zeichenfolge und wusste nicht, dass' char line [128] = "whatever" anders funktioniert. Oder wusste von letzterem überhaupt nichts. – derobert

1

Es ist überflüssig, weil strcpy() es trotzdem tun wird.

2

Es tut nichts. Es versucht, eine bereits abgeschlossene Zeichenfolge auf Null zu setzen.

2

ich Sieht aus wie es ist ein Null-Terminator (Char 0) am Ende der Daten platzieren es in tempstr mit strcpy() kopiert hat.

strcpy(tempstr, line) 

Kopiert den Inhalt der Linie in tempstr, aber der Autor ist vielleicht nicht sicher, ob tempstr wird null nach dieser Operation beendet werden. Mein C ist rostig, und um fair zu sein, bin ich mir auch nicht sicher. :)

jedoch für den Code, wie beabsichtigt zu arbeiten ich denke, Linie und damit tempstr muss bereits Nullterminiert werden (strlen (Linie) zur ersten Nullabschluss zählen wird), Damit der Code wie erwartet funktioniert, muss er auch absolut redundant sein, da strcpy() den Nullabschluss kopiert hat, als er Zeile an erster Stelle kopiert hat!

, d.h.// Confusing Teil ist eigentlich eine Null-Operation und kann entfernt werden. :)

1

Es hilft zu verstehen, dass String-Konstanten wie "AUTO_ANSWER_CALL = 1" angenommen werden müssen, um unveränderlich zu sein. Also, was geht hier zwei String-Puffer deklariert sind:

char line[128], tempstr[128]; // <== better have the semicolon 

an dieser Stelle ihren Inhalt sind völlig unbekannt.

Als nächstes wird ein vorbereiteter Text in einen von ihnen kopiert.

strcpy(line, "AUTO_ANSWER_CALL = 1"); 

und dann in die andere

strcpy(tempstr,line); 

Endlich ein wenig Zeigerarithmetik wird verwendet, um ein Null-Zeichen '\0' == 0x0 auf das Ende zu kleben die Zeichenfolge, um sicherzustellen, dass ordnungsgemäß beendet wird:

*(tempstr + strlen(line)) = (char) 0x0; // Confusing part 

entspricht

tempstr[strlen(line)] = (char) 0x0; 
Diese
2

Wie von anderen hier erwähnt, fügt der Code grundsätzlich ein '\ 0' am Ende der Zeichenfolge hinzu, obwohl es bereits vorhanden ist. Ist das alles der Code oder gibt es Zeilen dazwischen? Es könnte einen Sinn ergeben, wenn ein memcpy() zwischen diesen Zeilen verwendet wird. Auf der helleren Note wurde der Code wahrscheinlich von einem kurzsichtigen Geek geschrieben, der an einem Minderwertigkeitskomplex litt.

+0

Die Zeile wird mit fgets aus einem Dateizeiger initialisiert. Ich habe es hier hinzugefügt, um den Code einfacher zu machen. Ich bin mir aber sicher, dass es noch andere Möglichkeiten gibt, einen String zu beenden. – ant2009