/ / Müll produzieren mit fread - c ++

Produce Müll mit der Verwendung von fread - C ++

Ich möchte die Daten mit fread aus lesenDatei. Ich stoße jedoch auf das Problem der Einstellung von NULL-Abschlusszeichen. Allerdings bekomme ich immer noch Müll bei dem ich den Wert von "fileMem" überprüfe. Würde mir jemand helfen, das Problem zu finden?

Ich habe anderen Posts über das Setzen des NULL-Terminators gefolgt, funktioniert aber einfach nicht

File *input = fopen(filePath, "r");
fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);
fseek(input, 0, SEEK_SET);
char* fileMem = new char[fileSize+1];
fileMem[fileSize] = 0;// the NULL terminator problem should have been solved here
clearerr(input);
fread(fileMem, fileSize,1, input);

Was ist das Problem mit meinem Code?

Antworten:

1 für die Antwort № 1

fread liest mehr Bytes als fileSize,weil Sie eine Datensatzgröße von fileSize angeben und es auffordern, nur einen Textdatensatz zu lesen. Es überschreibt dann die 0 am Ende mit den tatsächlichen Daten, so dass Sie Müll bekommen.

fread gibt die Anzahl der tatsächlich gelesenen Bytes zurück. Sie können also einen größeren Puffer zuweisen und dann den Rückgabewert von fread verwenden, um zu bestimmen, wie viel davon gültig ist (und einen Null-Terminator festlegen).

Da Ihre Daten auf diese Weise aktualisiert werden, empfehle ich auch, den Dateityp in binär zu ändern ("rb" statt "r" im Aufruf von fopen).

Der Grund dafür ist, dass fread im Textmodus ("r" statt "rb") Text übersetzt, z.


1 für die Antwort № 2

Angenommen, Sie sind unter Windows, ich denke, das Problem ist, dass Sie die Datei im Textmodus öffnen und verwenden fread was für den binären Modus gedacht ist. Im Textmodus ist das, was Sie lesen, möglicherweise nicht genau das, was in der Datei enthalten ist. Windows-Textdateien haben "rn" am Ende der Datei, aber im Textmodus wird diese Kombination aus zwei Zeichen in ein einzelnes Zeichen "n" umgewandelt. Also die fileSize Ihr berechneter Wert ist zu groß, und Ihr Nullterminator befindet sich an der falschen Stelle.

Um dies zu überprüfen, ändern Sie Ihre fread sein:

int nr = fread( fileMen, 1, fileSize, input);

Die mittleren args tauschen, wird haben fread Gibt die Anzahl der gelesenen Bytes zurück. Wenn Sie den Wert von betrachten nrwird kleiner sein als fileSize wegen der Zeilenende-Übersetzung.

Dies wäre auf einem * nix-System kein Problem, da im Textmodus keine Übersetzung vorhanden ist.


0 für die Antwort № 3

Wann möchten Sie verwenden? fread Um den Inhalt einer Datei lesen zu können, müssen Sie die Datei im Binärmodus öffnen.

FILE *input = fopen(filePath, "rb");
^^

Andernfalls die Größe der Datei, die Sie verwenden

fseek(input, 0, SEEK_END);
auto fileSize = ftell(input);

wird größer als die Anzahl der Zeichen, mit denen gelesen werden kann fread.

Wenn Sie über eine CR und eine LF verfügen, werden sie mit der obigen Methode als zwei Zeichen gezählt fread liest nur ein Zeichen. Daher, fread wird weniger lesen als fileSize Zeichen. Sie können auch das ändern fread Linie zu:

// Swap the middle arguments.
// The first argument is supposed to be the size of each object.
// The second argument is supposed to be the number of objects to read.
auto n = fread(fileMem, 1, fileSize, input);
if ( n != fileSize )
{
// Surprise
}
fileMem[n] = "";