2017-09-20 1 views
-1

Ich habe ein kleines Problem beim Experimentieren mit C-Code. Ich habe versucht, mit read() - Command einen Text aus einer Datei zu lesen und die Ergebnisse in einem charArray zu speichern. Aber wenn ich die Ergebnisse drucke, unterscheiden sie sich immer von der Datei. HierC UNIX - read() liest keine existierenden Buchstaben

ist der Code:

#include <stdio.h> 
#include <fcntl.h> 
#include <unistd.h> 

void main() { 

int fd = open("file", 2); 
char buf[2]; 
printf("Read elements: %ld\n", read(fd, buf, 2)); 
printf("%s\n", buf); 
close(fd); 

} 

Die Datei "Datei" wurde im gleichen Verzeichnis mit dem folgende UNIX erstellt Befehle:

cat > file 
Hi 

So enthält es nur das Wort "Hallo". Wenn ich es ausführe, erwarte ich, dass es 2 Bytes aus der Datei liest (die "H" und "I" sind) und sie bei buf [0] und buf [1] speichern. Aber wenn ich das Ergebnis drucken möchte, scheint es, dass es ein Problem gab, weil neben dem Wort "Hi" mehrere seltsame Zeichen gedruckt sind (was auf ein Speicherlese-/Schreibproblem hindeutet, das ich aufgrund der schlechten Puffergröße vermute). Ich habe versucht, die Größe des Buf-Array zu erhöhen, und es scheint, dass, wenn ich die Größe ändere, die seltsamen Zeichen sich ändern. Das Problem wird entfernt, wenn die Größe 32 Byte erreicht.

Kann mir jemand im Detail erklären, warum das passiert? Ich habe bis jetzt verstanden, dass read() nicht '0' liest, wenn es etwas liest, und dass der dritte Parameter von read() die maximale Anzahl der zu lesenden Bytes angibt.

Antoher Sache, die ich beim Experimentieren mit dem obigen Code festgestellt habe, ist Folgendes: Nehmen wir an, man ändert den dritten Parameter (maximal zu lesende Bytes) von read() zu 3 und die Größe von buf-Array zu 512 (Overkill ich weiß, aber ich wollte wirklich sehen, was passieren wird). Jetzt liest man ein drittes Zeichen (in meinem Fall 'e') und speichert es in den Puffer, auch wenn dieses dritte Zeichen nicht existiert.

Ich habe schon eine Weile gesucht @StackOverflow und ich fand viele ähnliche Fälle, aber keine von ihnen hat mich mein Problem verstehen lassen. Wenn es einen anderen Thread gibt, den ich vermisst habe, wäre es eine Freude, wenn du mich damit verlinken könntest.

Endlich: sry für mein schlechtes Englisch, es ist nicht meine Muttersprache.

+1

'char buf [3];' lesen dann null terminieren 'buf [2] = '\ 0';' das wird es tun. –

+1

Mögliches Duplikat von [Einfachster Weg, den Inhalt der Datei in C zu erhalten] (https://stackoverflow.com/questions/174531/easiest-way-to-get-files-contents-in-c) –

+1

'printf ("%. * s \ n ", (int) n, buf);', wobei 'n' die Zahl ist, die du von' read' zurückbekommen hast. –

Antwort

1

Natürlich müssen Sie buf 3 Bytes lang und verwenden Sie das letzte Byte als Null-Byte (0 oder '\0'). Auf diese Weise wird der Computer beim Drucken der Zeichenfolge nicht fortgesetzt, bis er eine andere 0 findet!

Die Art und Weise, wie Zeichenfolgen (char-Arrays) in C behandelt werden, ist ziemlich einfach. In der Tat, wenn es sich um Strings handelt (am meisten), wenn nicht alle Funktionen davon ausgehen, dass die String-Parameter null terminiert (puts) sind oder null terminierte Strings zurückgeben (strdup).

Der Punkt ist, dass der Computer standardmäßig nicht sagen kann, wo eine Zeichenfolge endet, es sei denn, es wird die Zeichenfolgengröße jedes Mal, wenn er es verarbeitet. Die einfachste Implementierung dieses Ansatzes bestand darin, nach jedem String eine 0 anzuhängen (nämlich das Null-Byte). Auf diese Weise muss der Computer nur über die Zeichen der Zeichenfolge iterieren und stoppt, wenn er das Beendigungszeichen (anderer Name für Nullbyte) findet.

+0

Nehmen wir an, dass ich ein Char-Array-Zeichen anotherBuf [2] fest codiere und H bei [0] und i bei [1] zuweist.Dann kann ich printf ("% s", anotherBuf) verwenden und es druckt das char Array auch ohne das abschließende 0 korrekt. Es sucht nicht nach dem "nächsten" '\ 0', das es finden kann. Warum ist das bei meinem Char-Array nicht dasselbe? In der Tat: Es sollte nur 'H' und 'i' nach read() enthalten. – Tmirror

+0

@Tmirror Dieser Test konnte nicht garantiert werden; Zufällig war es zufällig ein Null-Byte, kurz nachdem 'anotherBuf' für' printf' gefunden wurde und aufhörte. –

+0

Das Drucken einer nicht nullterminierten Zeichenkette in C ist ** garantiert **, um Ihnen zusätzlichen Müll zu geben, solange kein Nullbyte gefunden wird. –