1. fopen() ist C Code und nicht C++ Code. Die C++-Variante würde ifstream heißen. (Dies ist die Klasse von der man Objekte zum Einladen von Dateien bildet).
2. fopen() öffnet nur die Datei und stellt einen Pointer zu dieser Datei her. Damit ist noch kein Inhalt eingelesen worden. Dafür gibt es Funktionen wie fread().
3. Hexadezimalwerte sind in C/C++ (meist) Speicherstellen. Wenn du so etwas angezeigt bekommst, ist das die Speicherstelle einer Variablen oder sonst eines Objekts im Speicher. Dann hast du wohl einen Pointer anstelle dessen "gepointeten" Wert ausgeben lassen.
In deinem Fall aber gibst du einen Pointer auf ein Dateiobjekt aus, was überhaupt keinen Sinn (oder zumindest nicht den von dir gewünschten) hat. Du brauchst da noch einen Speicherbereich in den eingelesen wird und musst dann mittels fread() dort Daten aus dem Dateiobjekt "datei" einlesen.
Ich würde dir aber dennoch die C++ Methode empfehlen, denn diese ist einfacher und auch zeitgemäßer, wenn du sowieso C++ programmieren willst.
Diese findest du im header "fstream", Klasse hab ich gesagt, ist die ifstream und ofstream (dann gibts afaik auch noch nur fstream und sicher ein paar Abwandelungen, brauchte ich bisher nicht...).
Ein Beispiel für das Einlesen einer Datei in C++ :
(Im gleichen Verzeichnis wie der Sourcecode muss eine "Datei.txt" Datei mit beliebigem Inhalt vorhanden sein (mindestens 11 Zeichen)).
Die simple Methode ist die erste, dabei werden per Stream-Operatur "<<" aus dem geöffneten "Dateistrom" so viele Byte entnommen, wie in die Variable rechts davon passen. Hier ein Byte, da es eine char Variable ist. Diese Variable nimmt dann den Inhalt an. Sehr mühsam wenn man große Datenmengen auslesen will.
(Ob man auch Speicherbereiche so angeben kann weiß ich nicht. Jedenfalls ist diese Methode zwar simpel aber Methode 2 würde ich empfehlen).
Die Methode 2 ließt so viele Byte ein, wie im letzten Parameter angegeben. Vorher muss aber ein Bereich mittels malloc() im Speicher reserviert werden, wo die Daten rein kommen. Wichtig ist hier, dass jeder String mit einem 0-Zeichen (Null) abschließen sollte da es sonst Fehler geben kann und wird. Deshalb musst du ein Byte mehr reservieren als du einlesen willst. Das letzte Zeichen muss 0 sein. Damit ich nicht rumfischen muss im letzten Byte, setze ich vor dem Einlesen per memset() alle Zeichen erst einmal auf 0. Jetzt werden 9 Zeichen in die 10 vorhandenen Stellen eingelesen, die letzte bleibt 0.
Beim Ausgeben von Speicherstellen kann man über Cout auch einfach den char-Pointer angeben, cout nimmt dann automatisch den Wert an der Speicherstelle, also den String, und gibt nicht die Speicherstelle selbst aus (Das Hexadezimale Zeugs von oben etwa).