Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Problem bei txt-öffnen

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
08.08.2007, 21:05 Uhr
Doping



Hi,
mein Programm soll eine txt-datei einlesen und damit was machen. Mein Problem ist: wenn ich den Dateinamen direkt in den Konstruktor eingebe("test.txt") funktionierts. Wenn ich aber nach Dateiname frage und das test.txt eingebe findet das Programm die Datei nicht


C++:
#include <iostream>
#include <fstream>
#include <string.h>
#include <conio.h>
using namespace std;

main() {
    char datei;
    cin >> datei;
    fstream indatei(datei, ios::in);                                        
    if(!indatei) {
        cout << "Datei konnte nicht gefunden werden!";
        getch();
        return 0;
    }
    //ect.
}


Woran liegt das?
thx für eure Antworten
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
08.08.2007, 21:33 Uhr
0xdeadbeef
Gott
(Operator)


char bedeutet ein einzelnes Zeichen, und nicht, wie du willst, eine Zeichenkette. Es wäre möglich, das mit char* zu machen, aber die manuelle Speicherverwaltung muss man sich eigentlich nicht antun, und

C++:
char *dateiname; // dangling pointer!
std::cin >> dateiname; // Speicherzugriffsfehler


wird zwar kompilieren, aber sich nicht ausführen lassen, weil dateiname nicht auf einen Speicherbereich zeigt, in den du einlesen darfst. Die einfachste Methode wäre, std::string zu benutzen, das sieht dann so aus:

C++:
#include <iostream>
#include <fstream>
#include <string>

int main() { // In C++ und C99 muss int explizit angegeben werden
  std::string dateiname;

  // Besser die ganze Zeile einlesen, für den Fall, dass Leerzeichen im
  // Dateinamen enthalten sein sollen. Außerdem bleiben so keine Rückstände
  // im Eingabestream. std::cin >> dateiname; ist auch möglich, aber hier
  // weniger gut.
  std::getline(std::cin, dateiname);

  std::ifstream indatei(datei.c_str());

  if(!indatei) {
    std::cerr << "Datei konnte nicht gefunden werden!";
    // Typischerweise will man im Fehlerfall nicht 0 zurückgeben,
    // weil das konventionell für die Shell eine Erfolgsnachricht bedeutet
    return -1;
  }

  // ...
}


--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 08.08.2007 um 21:34 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
08.08.2007, 21:54 Uhr
Doping



Danke für die Hilfe, aber warum darf ich nicht auf dem Speicherbereich einlesen?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
08.08.2007, 22:05 Uhr
0xdeadbeef
Gott
(Operator)


Der Zeiger ist nicht initialisiert, und kann daher eigentlich überallhin zeigen. Mit aller Wahrscheinlichkeit bedeutet das, er zeigt auf einen Bereich im virtuellen Adressraum, der noch nicht auf eine vom Kernel angeforderte Speicherpage zeigt. Dementsprechend kann der Kernel das nicht auf einen physikalischen Speicherbereich mappen und schmeißt einen segmentation fault. Schlimmer noch wäre es, wenn der Zeiger auf einen Speicherbereich zeigt, der dir bereits gehört - dann geht dir ganz schnell der Heap oder Stack kaputt, und dein Programm macht allen möglichen Unfug.

Kurz, in uninitialisierte Zeiger zu schreiben erzeugt undefiniertes Verhalten, und ist dementsprechend falsch. In aller Regel wird es dir segmentation faults erzeugen und das Programm zum Absturz bringen, und wenn es das nicht tut, sind die Folgen im Zweifel noch schlimmer.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
08.08.2007, 22:30 Uhr
~nanu
Gast


@Doping schrieb: ... , aber warum darf ich nicht auf dem Speicherbereich einlesen?

So hätte Dein Programm funktioniert:


C++:
#include <iostream>
#include <fstream>
//#include <string.h>
#include <conio.h>
using namespace std;

int main()
{
    char datei[256]; // Speicher für 256 char auf dem Stack reserviert !
    cin >> datei;
    fstream indatei(datei, ios::in);                                        
    if(!indatei) {
        cout << "Datei konnte nicht gefunden werden!";
        getch();
        return 0;
    }
    //ect.
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.08.2007, 03:05 Uhr
0xdeadbeef
Gott
(Operator)


So etwas würde ich mir aber nach Möglichkeit gar nicht erst angewöhnen, vor allem, wenn eine bessere Alternative bereitsteht (std::string, hint, hint). Wenn dir da jemand mehr als 256 Zeichen eingibt, schreibt das fröhlich weiter auf den Stack und über die Rücksprungadresse - in diesem Fall würde das Programm dann einfach abstürzen, aber stell dir vor, sowas passiert zum Beispiel in einem Webserver und er schreibt ein bisschen Code in den Buffer und die Rücksprungadresse so, dass das Programm danach in diesen Code springt. Kannst du "remote exploit" sagen?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
09.08.2007, 14:30 Uhr
xXx
Devil


nja ...

C++:
char file_name[256];
std::getline(std::cin, file_name, 256);
aber vergess das schnell wieder ^^ Mach es mit std::string ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: