Soweit ist mir das klar ...
1 | |
2 | |
3 | |
4 | |
5 | |
was ich nicht verstehe:
> buffer[res]=0; <
Wen 'res' die gelesenen Elemente sind, schreibt das an die
Postion eine '0'?
|h|a|l|l|o| |w|o|r|l|d|0| | | | | | | | | | | ... | | | | | | |
???
|
Anzeige
|
buffer[res]=0;Soweit ist mir das klar ...
was ich nicht verstehe:
> buffer[res]=0; <
Wen 'res' die gelesenen Elemente sind, schreibt das an die
Postion eine '0'?
|h|a|l|l|o| |w|o|r|l|d|0| | | | | | | | | | | ... | | | | | | |
???
Gast
#3008573
Hallo,
> buffer[res]=0;
der Aufruf read liefert im Erfolgsfall die Anzahl der gelesenen Bytes.
Um dann den Puffer als Zeichenkette ausgeben zu können, muss am Ende ein
Null-Byte angehängt werden. Anderenfalls weiß printf nicht, wann der
Puffer zu Ende ist.
Gruss
Micha
Gefährlich. Bei einem I/O-Error oder EOF gibt read eine -1 zurück. Was dann passiert kann seht interessant werden ;) Erst auf Fehler testen, dann erst res verwenden.
Gast
#3008597
Die Implementierung ist auch nicht ganz richtig. Falls read() wirklich so viele Bytes liest wie Buffer groß ist, schreibst du in der nächsten Zeile über das Array hinaus. besser wäre: res = read(fd, buffer, sizeof(buffer) - 1); Henrik Wellschmidt schrieb: > Wen 'res' die gelesenen Elemente sind, schreibt das an die > Postion eine '0'? Hallo Henrik, zum Verständnis sind ein paar C-Grundlagen wichtig: 1. Die Zählung der Elemente des Arrays beginnt bei 0. Liest die Routine res Zeichen ein, stehen die auf den Speicherstellen buffer[0] bis buffer[res - 1]. buffer[res] ist die erste Speicherstelle nach den eingelesenen Zeichen. 2. 0 und '0' sind zwei ganz verschiedene Dinge. 0 steht den numerischen Wert 0 dar (0b00000000 bzw. 0x00). '0' ist die ASCII-Codierung der Zeichens der Ziffer 0. 3. In C wird das Ende einer Zeichenketten (String) mit eine "Endemarke" gekennzeichnet, und zwar steht an der letzten Stelle der numerische Wert 0. Die Zeichenfolge "Hello World!" besteht also tatsächlich aus {'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '!', 0}. buffer[res]=0 erzeugt diese Endemarke. Grüße Stefan PS: Du solltest in jedem Fall auch prüfen, ob res >= sizeof(buffer) ist. buffer[sizeof(buffer)] ist die erste Speicherstelle hinter buffer, da liegt mit Sicherheit was anderes... Danke für eure Antworten :-) Das hilft mir weiter! -- C hat echt Suchtpotential ... Besser?
Gast
#3008676
ja, besser. wird noch besser wenn du die {} weglaesst, und res=0; hinter
die if abfrage schreibst.
Gast
#3008679
und > durch < ersetzt.
Gast
#3008694
dadada schrieb: > ja, besser. wird noch besser wenn du die {} weglaesst, und res=0; hinter > die if abfrage schreibst. dadada schrieb: > und > durch < ersetzt. Du willst bei einem Fehler so tun, also ob EOF wäre? Das wird ja ein tolles Programm. dadada schrieb: > ja, besser. wird noch besser wenn du die {} weglaesst, und res=0; hinter > die if abfrage schreibst. Ahhh, verstehe :-D
Das '=' brauch ich auch nicht mehr? 0=0? Stefan Wagner schrieb: > PS: Du solltest in jedem Fall auch prüfen, ob res >= sizeof(buffer) ist. Wenn das passiert, ist read() fehlerhaft und hat wahrscheinlich über den Puffer hinausgeschrieben. Dann ist es also schon zu spät. Man kann natürlich versuchen, das Programm noch geordnet abzubrechen, aber im Prinzip kann man sich dann auf nichts mehr verlassen. Henrik Wellschmidt schrieb: > Ahhh, verstehe :-D Gewöhn Dir lieber leserliche, einheitliche und fehlervermeidende Codeformatierung an. Das heißt: Immer Klammern setzen und jede Anweisung in eine eigene Zeile:
Damit passiert im Fehlerfall das gleiche wie wenn ein leerer String gelesen wurde. Ob das ist was Du willst, musst Du wissen. Du könntest den Fehler auch dem Benutzer melden, es später nochmal probieren, etc. Fabian O. schrieb: >> res >= sizeof(buffer) ist. > > Wenn das passiert, ist read() fehlerhaft und hat wahrscheinlich über den > Puffer hinausgeschrieben. res == sizeof(buffer) wäre im ursprünglichen Code möglich gewesen. Die Abfrage res >= sizeof(buffer) war meinem "Sicherheitsbedürfnis" ("paranoid coding" :-) ) geschuldet. Grüße Stefan Fabian O. schrieb: > Gewöhn Dir lieber leserliche, einheitliche und fehlervermeidende > Codeformatierung an. Das heißt: Immer Klammern setzen und jede Anweisung > in eine eigene Zeile: Okay! Mac schrieb: > Du willst bei einem Fehler so tun, also ob EOF wäre? Das wird ja ein > tolles Programm. Was ist mit Mac seinem Einwand ...
??? Darf ich mich hier mal einmischen? > res = read(fd, buffer, sizeof(buffer) - 1); > > if (res < 0) { > res = 0; > } etwas Derartiges ist eine ganz schlechte Idee. Alle Lesefunktionen sind in C so gestaltet, dass man mit ihrem Rückgabewert unmittelbar die umgebende Schleife steuern kann, die den Einlesevorgang solange wiederholt, bis keine Daten mehr da sind. Etwas weiter ausgeholt: Man sieht oft, durchaus auch in Lehrbüchern, Leseschleifen dieser Gestalt (symbolische Schreibweise) File = fopen( .... ) while( !feof( File ) ) { read process } fclose( File ); und genau das ist die Form, die man in C nicht macht! Das Runtime System von C versucht nicht in die Zukunft zu sehen und das eof zu erahnen. Statt dessen ist ein eof Teil des Returnwertes des Read (wie auch immer das dann bei der konkreten Lesefunktion aussieht). D.h. eof wird erst dann erkannt, wenn ein Leseversuch gestartet wird und dieser Leseversuch als ganzes schief geht. Zum Beispiel geht er schief, weil ein eof aufgetreten ist. Er kann aber auch zb deswegen schief gehen, weil jemand die CD aus dem Laufwerk genommen hat oder weil die Netzwerkverbindung abgerissen ist oder .... Es gibt viele Möglichkeiten, warum ein Leseversuch schief gehen kann, eof ist nur einer davon. Die korrekte Art und Weise, wie man in C Files einliest, sieht dem Prinzip nach so aus File = fopen( .... ) while( read .... liefert keinen Fehler ) { process } if( ! eof( File ) ) { Fehlermeldung ausgeben: Irgendwas ist beim Lesen schief gelaufen Eventuell Zusatzinformation für die Fehlerursache besorgen } fclose( File ) D.h. man zerstört sich NICHT den Returnwert vom read, sondern benutzt ihn um damit die Schleife zu steuern. Meldet der read auf die Art einen Fehler (in diesem konkreten Fall, in dem er einen negativen Wert liefert. Andere read-Funktionen liefern was anderes), dann wird die Schleife beendet und festgestellt, warum sie beendet wurde. War es, weil eof aufgetreten ist, dann ist alles paletti, das File wurde komplett gelesen. In allen anderen Fällen gab es irgendeinen Fehler, den man gegebenenfalls weiter ergründen muss. Und ich vergass:
Dafür gibt es auch eine typische Foren/Newsgroup Fehler-Anfrage.
Sie lautet: Warum wird in meinem Programm die letzte Eingabe
(Eingabezeile) doppelt bearbeitet?
Und noch ehe man den Code sieht, kann man seine 4 Buchstaben darauf
verwetten, dass man im Code genau diese Struktur
while( !feof( File ) )
{
read
process
}
finden wird. Das ist das typische Symptom dafür.
Daran hab ich erstmal n Abend zu knabbern :-) Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|