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 № 1fread 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 nr
wird 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] = " ";