Problem mit Pointer und NULL-Zeichen

Newtonianer

Grünschnabel
Hallo Zusammen,

ich bin C++ Einsteiger und habe fürs Studium eine Aufgabe gestellt bekommen. Ich habe sie schon beinahe gelöst, nur die Abbruchbedingung bereitet mir Kopfzerbrechen.

Es soll eine Textdatei (txt) ZEICHENWEISE eingelesen und ausgegeben werden und man soll dabei auf Pointer zurückgreifen.

Code:
char* filePtr = readFile("beispiel.txt");
    for (char** Ptr = &filePtr; *filePtr!='\0x00'; *++filePtr)
    {
        cout << *filePtr << '\n';
    }

Die readFile-Funktion wurde uns schon vorgegeben und ist bereits programmiert, mein eigentliches Problem ist die Abbruchbedingung in der for-Schleife: *filePtr!='\0x00'
Ich will also beim NULL-Zeichen abbrechen, welches ja normalerweise am Ende der Textdatei stehen sollte.

Seltsam ist folgendes: Der filePtr hat folgenden Inhalt aus der txt-Datei:
Hallo, ich bin eine Textdatei zum Testen!ýýýý««««««««þîþ
Diese ganzen Zeichen nach Testen! sind allerdings nicht in der Datei "sichtbar" abgespeichert, die müssen also wohl irgendwie übers Notepad dazugekommen sein. Weiterhin funktioniert meine Abbruchbedingung in der for-Schleife nicht, weil die Zeichen nach "Testen!" einen negativen Wert und nicht 0 haben.
Diese Zeichen nach "Testen!" kommen übrigens immer vor, egal wie der in der txt-Datei abgespeicherte Text ist.
Achja, ich arbeite mit Visual Studio 2005.

Ich hoffe mir kann jemand helfen, bin echt schon am Verzweifeln :rolleyes:.

Gruß,
Tobi
 
Ich will also beim NULL-Zeichen abbrechen, welches ja normalerweise am Ende der Textdatei stehen sollte.
Was am Ende einer Textdatei steht ist völlig unvorhersehbar und eine NULL steht dort in der Regel nicht.
In deinem Fall wäre es interessant zu wissen, wie denn die readFile()-Funktion funktioniert. Mir scheint, sie erkennt nicht korrekt das Dateiende.

Gruß
MCoder
 
Und du hast da ein * zu viel drin :P

C++:
const char* ptr_content = readFile("beispiel.txt");
for (const char* ptr_it = ptr_content; *ptr_it != 0; ++ptr_it) std::cout << *ptr_it << "\n";
wäre dein Beispiel, wenne s korrekt wäre :D bzw. wenn readFile korrekt Nullterminieren würde ;)
 
Hallo Zusammen,

@devDevil: ich habe gerade deinen Code mal verwendet, das führt noch immer zum gleichen Ergebnis - der Pointer bricht nicht nach dem letzten Zeichen aus der Textdatei ab.

Anbei mal der gesamte Code:
C++:
#include<iostream>
#include<fstream>


using namespace std;

//----------------------- Prototyp für Funktion, die Datei einliest
char* readFile(char* filename);

// Hauptprogramm
int main ()
{
    //------------------------------------------ Einlesen des Texts

const char* filePtr = readFile("beispiel.txt"); 
     
    //------------------------------------------- Ausgabe des Texts 
    /* TODO (1): Geben Sie den Inhalt des Pointers ZEICHENWEISE
     *           auf der Konsole aus.
     * Hinweis: Kopieren Sie dafür den Pointer zunächst in eine zweite
     *          Variable, sozusagen als "Arbeitskopie"
     */
 
for (const char* ptr_it = filePtr; *ptr_it != 0; ++ptr_it) 
{
std::cout << *ptr_it << "\n";
}  
    
{

    //--------------------------------- Programm am Ende "anhalten"
    cin.get();
    }}

char* readFile(char* filename)
{
    FILE* fStream;

    if(!(fStream = fopen(filename, "r+")))
    {
        cout << "Konnte Datei \"beispiel.txt\" nicht laden";
        cout << "\nBeliebige Taste eingeben, um Programm zu beenden!";
        cin.get();
        exit(0);
    }

    fseek(fStream, 0L, SEEK_END);
    long filesize = ftell(fStream);
    fseek(fStream, 0L, SEEK_SET);

    char* filePtr = (char*) calloc(filesize, sizeof (char));
    fread(filePtr, sizeof (char), filesize, fStream);
    
    return filePtr;
}

Alles zwischen dem Kommentar ab TODO(1) und "Programm am Ende anhalten" ist von mir, der komplette Rest war vorgegeben. Mit dem unteren Teil kennen wir uns auch noch gar nicht aus...

Viele Grüße,
Tobias
 
Zuletzt bearbeitet:
Hallo,

füge in der readFile-Funktion direkt vor "return filePtr;" mal diese Zeile ein:
C++:
filePtr[filesize - 1] = '\0';
Dem eingelesen Text fehlt die terminierende NULL.

Gruß
MCoder
 
Na gut dann darfst du deinen Prof. hiermit als unfähig abstufen :D Du hast ja keine Chance die Größe zu ermitteln :P Es sei denn du fügst die Nullterminierung ein ... davon mal abgesehen das du hier die Speicherverwaltung von C benutzt, was man eigtl. möglichst in C++ vermeiden sollte. Unter C++ gibt es sowas schönes wie std::ifstream. Davon mal abgesehen das die Fehlerbehandlung so ziemlich doof ist. Da so die Funktion nicht wiederverwendbar ist ... hier wäre return NULL wesentlich sinnvoller. (oder Exception :))
 
Hey Leute,

ich danke soweit mal für die Hilfe, mit MCoders Modifikation gehts so halbwegs, allerdings wird dann immer das letzte Zeichen in der txt-Datei nicht ausgegeben.

Mir ist da gerade noch so eine Idee gekommen: Könnte man nicht den Text irgendwie in ein Array einfügen? Habe gerade in meinen Unterlagen gelesen, dass ein Array automatisch als letztes Zeichen das \0 hat und der Compiler dies erkennt... ich wüsste aber nicht, wie ich das umsetzen könnte, aber für machbar halte ichs... aber dann übersteigt es wohl unsere bisherigen Fähigkeiten.

Viele Grüße,
Tobi
 
Ein Array hat als letztes Zeichen NICHT automatisch NULL,
und der Compiler kümmert sich im Regelfall NICHT darum...
ich schließe mich devdevil an, dein Prof ist unfähig :-)
 
allerdings wird dann immer das letzte Zeichen in der txt-Datei nicht ausgegeben.
Hab ich in der Eile übersehen (war kurz vorm Feierabend) :-)
Für das abschließende Nullzeichen muss natürlich auch noch Speicher reserviert werden. Dann klappt's auch mit dem letzten Zeichen
C++:
char* filePtr = (char*) calloc(filesize + 1, sizeof (char));
fread(filePtr, sizeof (char), filesize, fStream);
filePtr[filesize] = '\0';
Habe gerade in meinen Unterlagen gelesen, dass ein Array automatisch als letztes Zeichen das \0 hat und der Compiler dies erkennt...
Ein Array enthält nur das was man entweder hereinschreibt oder was zufällig im alloziierten Speicher drinsteht. Steht das tatsächlich so in den Unterlagen?
Übrigens gibt die readFile() ja schon ein Array zurück. Wie das da mit der automatischen Null aussieht, hast du ja schon festgestellt.

BTW:
- Der in readFile() reservierte Speicher sollte auch wieder freigegeben werden. Am Programmende daher bitte noch mit free(filePtr); wieder freigeben.
- // EDIT: Außerdem muss die Datei natürlich wieder geschlossen werden: fclose(fstream);

Gruß
MCoder
 
Zuletzt bearbeitet:
Zurück