Forum: PC-Programmierung zeilenweise lesen aus einer Textdatei


von Seprendium Diagnostica (Gast)


Lesenswert?

Hallo,

ich programmiere mit VC++ .Net.

ich habe eine Form erstellt. jetzt will ich, dass beim Formladen, die 
erste zeile einer textdatei geladen wird, und in eine textbox 
geschrieben wird.
Bis jetzt habe ich nur die funktion für das schreiben:
1
FILE* txtfile; 
2
txtfile = fopen("dateipfad","w"); 
3
fprintf(txtfile, "%s", "Hallo"); 
4
fclose(txtfile);

Aber ich habe keinen plan wie ich jetzt das lesen machen soll.
Kann mir jemand sagen, wie man bestimmte Zeilen einer Textdatei einlesen 
kann?

danke,


Seprendium Diagnostica

von Karl H. (kbuchegg)


Lesenswert?

Seprendium Diagnostica wrote:
> Hallo,
>
> ich programmiere mit VC++ .Net.
>
> ich habe eine Form erstellt. jetzt will ich, dass beim Formladen, die
> erste zeile einer textdatei geladen wird, und in eine textbox
> geschrieben wird.
> Bis jetzt habe ich nur die funktion für das schreiben:
>
>
1
> FILE* txtfile;
2
> txtfile = fopen("dateipfad","w");
3
> fprintf(txtfile, "%s", "Hallo");
4
> fclose(txtfile);
5
>
>
> Aber ich habe keinen plan wie ich jetzt das lesen machen soll.
> Kann mir jemand sagen, wie man bestimmte Zeilen einer Textdatei einlesen
> kann?

bestimmte Zeilen: gar nicht. Zumindest nicht einfach so.

Aber man kann eine einzelne Zeile mittels fgets() einlesen.
Will man also die 5. Zeile lesen, so liest man 4 Zeilen und
macht einfach nichts mit dem Gelesenen. Erst die Daten
des 5. Lesevorgangs werden dann bearbeitet.


Jetzt muss ich mich aber wundern. Welche Literatur verwendest
du, in der zwar das Schreiben von Dateien aber nicht das Lesen
aus Dateien behandelt wird?

(War eine rhetorische Frage. Worauf ich hinaus will: Besorg dir
Literatur. Da steht sowas und noch viel, viel mehr drinnen)

von Seprendium Diagnostica (Gast)


Lesenswert?

Das mit dem schreiben habe ich aus dem Internet.
Ich habe jetzt auch das lesen aus dem Internet:
1
FILE* txtfile;
2
char line[10];
3
int x;
4
5
if ((txtfile = fopen( "Dateiname", "r" )) != NULL)
6
{
7
   if( fgets( line, 10, txtfile ) == NULL)
8
   {
9
      MessageBox::Show("blabla");
10
   }
11
   else 
12
   {
13
  fgets( line, 10, txtfile );
14
  x = System::Convert::ToInt32(line);
15
   }
16
}
17
fclose(txtfile);

Aber wenn ich jetzt kompiliere, dann gibt er mir diese Warnung aus:

warning C4800: 'char *': Variable wird auf booleschen Wert ('True' oder 
'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)

ich weiß, was diese Warnung bedeutet (is ja net schwer), aber immer wenn 
ich die Form schließen will, stürzt das Programm ab. Auch wenn ich den 
Prozess im task manager schließe dauert das ein Weilchen.

Mein Frage: Kann ich da irgendetwas machen? Oder müsste ich, wenn ich 
die Form schließe noch irgentwelche dinge einprogrammieren von wegen 
Arbeitsspeicher leeren oder so?

ich würde mich für jeden Tipp freuen,

Seprendium Diagnostica

von Bobby (Gast)


Lesenswert?

Das Programm liest jede zweimal, auch wenn es die zweite Zeile
garnicht gibt:



FILE* txtfile;
char line[10];
int x;

if ((txtfile = fopen( "Dateiname", "r" )) != NULL)
{
   if( fgets( line, 10, txtfile ) == NULL)
   {
      MessageBox::Show("blabla");
   }
   else
   {
// das ist zuviel:::::  fgets( line, 10, txtfile );
  x = System::Convert::ToInt32(line);
   }
}
fclose(txtfile);

von Seprendium Diagnostica (Gast)


Lesenswert?

Danke für den Tipp, ich habs jetzt rausgenommen. ist mir auch klar 
geworden dass die Zeile unnötig war. trotzdem bleibt das Problem.

von Karl H. (kbuchegg)


Lesenswert?

An dem Ausschnitt ist erst mal so nichts falsch.

Was ich tun würde: Ich würde mich nicht darauf verlassen,
dass die Eingabezeile maximal 9 Zeichen enthält sondern
würde den Wert höher setzen. Viel höher. So auf 256 oder 512.
Allerdings ist das nicht unbedingt dein Problem. fgets
passt schon darauf auf, dass der angegebenen Buffer nicht
überlaufen wird. Und da fgets im Nichtfehlerfall auch immer
brav ein '\0' Zeichen ans Ende das Strings schreibt, ist
fgets auch eine sehr sichere Funktion.

Dein Problem muss also woanders liegen.

von Seprendium Diagnostica (Gast)


Lesenswert?

hi,

Es kann aber eigentlich nicht woanders liegen, dann vorher hat alles 
geklappt. Außerdem zeigt er ja diese Warnmeldung hier an:

warning C4800: 'char *': Variable wird auf booleschen Wert ('True' oder 
'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)

Aber diese Variable "line" muss doch ein boolschen Wert besiten, oder?
Wenn die zeile line nicht null ist ... wenn sie null ist...
eindeutig: (true/false)

Ich habe aber auch gar keinen plan wie ich das jetzt löse.

Seprendium Diagnostica

von Karl H. (kbuchegg)


Lesenswert?

Seprendium Diagnostica wrote:
> hi,
>
> Es kann aber eigentlich nicht woanders liegen, dann vorher hat alles
> geklappt.

Das heist nicht viel.

> Außerdem zeigt er ja diese Warnmeldung hier an:
>
> warning C4800: 'char *': Variable wird auf booleschen Wert ('True' oder
> 'False') gesetzt (Auswirkungen auf Leistungsverhalten möglich)
>

Wo genau, in welcher Zeile, wird diese Fehlermeldung gegeben?


> Aber diese Variable "line" muss doch ein boolschen Wert besiten, oder?
> Wenn die zeile line nicht null ist ... wenn sie null ist...
> eindeutig: (true/false)

Quatsch.
Du solltest wirklich zu Literatur greifen und mal von vorne
zu lesen anfangen.

Im ganzen geposteten Code gibt es nur eine Zuweisung und die
ist hier:
   x = System::Convert::ToInt32(line);

Wenn du jetzt mal in der Mikrosoft Doku nachsiehst, dann wirst
du feststellen, dass es kein ToInt32 gibt, welches ein
character Array (oder einen char Pointer, was in dem Fall
dasselbe ist) annimmt.

Du willst int::Parse()

oder von mir aus auch

   x = System::Convert::ToInt32( String( line ) );

(wobei ich für diese Version nicht bürgen würde, da ich sie
nicht probiert habe)

Aber: Selbst wenn du da den Pointer auf line hineinstopfst, wird
nichts passieren, was einen Absturz rechtfertigt. Du wirst eine
Seltsame Zahl zurückbekommen, ja. Mehr wird aber auch nicht
passieren.

(Wobei schon interessant ist, dass sich der Compiler für eine
Zwischenlösung über einen bool entscheidet)

von Karl H. (kbuchegg)


Lesenswert?

Eine reine C-Lösung, ohne das ganze .NET Geraffel, würde so aussehen:
1
FILE* txtfile;
2
char line[256];
3
int x;
4
5
if ((txtfile = fopen( "Dateiname", "r" )) != NULL)
6
{
7
   if( fgets( line, sizeof( line ), txtfile ) )
8
   {
9
     sscanf( line, "%d", &x );
10
   }
11
}
12
fclose(txtfile);

So kann man seit 30 Jahren aus einem String eine Zahl
herausholen. Und ev. solltest du das auch tun.

Literatur einkaufen nicht vergessen!

von Seprendium Diagnostica (Gast)


Lesenswert?

Hi

>Das heist nicht viel.

Wieso heißt das nicht viel? Ich habe noch 8 andere Objecte die das 
machen, was sie machen sollen. All das hat geklappt was klappen sollte!
0 Fehler 0 Warnungen.

>Wo genau, in welcher Zeile, wird diese Fehlermeldung gegeben?

In der Zeile.
1
x = System::Convert::ToInt32(line);

>Quatsch.

Wieso ist das Quatsch? Entweder die Zeile ist mit mindestens 1 Char 
beschrieben, oder nicht. Ist doch entweder true oder false.

Seprendium Diagnostica

von Karl H. (kbuchegg)


Lesenswert?

Seprendium Diagnostica wrote:
> Hi
>
>>Das heist nicht viel.
>
> Wieso heißt das nicht viel?

Weil die Stelle an der du einen Fehler bemerkst (in deinem
Fall den Absturz) nicht unbedingt etwas mit der identischen
Stelle im Code zu tun haben muss.

> Ich habe noch 8 andere Objecte die das
> machen, was sie machen sollen. All das hat geklappt was klappen sollte!
> 0 Fehler 0 Warnungen.

Das heist schon gar nichts mehr.
Der Compiler prüft nur ob deine Grammatik korrekt ist.
Ob dein Programm auch Sinn macht, ist dem COmpiler sowas von
egal.

"Ich laufe das Mitagessen mit dem Fernrohr."
ist rein grammatikalisch ein völlig korrekter deutscher Satz.
Trotzdem ergibt er keinen Sinn.

>
>>Wo genau, in welcher Zeile, wird diese Fehlermeldung gegeben?
>
> In der Zeile.
>
>
1
> x = System::Convert::ToInt32(line);
2
>
>
>>Quatsch.
>
> Wieso ist das Quatsch? Entweder die Zeile ist mit mindestens 1 Char
> beschrieben, oder nicht. Ist doch entweder true oder false.

Oh. Mann.
Literatur, Literatur, Literatur.
Online Tutorials sind zuwenig, wenn man in eine Programmiersprache
neu einsteigt und das die erste Sprache ist.

Ich hab in meinem vorhergehenden Posting noch Ergänzungen
vorgenommen. Dort mal nachlesen.

von Seprendium Diagnostica (Gast)


Lesenswert?

Hi,

Also. Ich versuche es nochmal. Ich wollte den Wert, den er in diesem 
Textfile in der ersten eile steht, einlesen. Aber bei mir gibt er nur 
True oder False an. True, wenn in dem Textfile etwas dirnsteht, False, 
wenn da nichts drinsteht.
Ich weiß zwar jetzt ob die Textdatei beschrieben ist oder nicht, aber 
nicht mit was.
Kann mir jemand sagen wieso?

Danke,

Seprendium Diagnostica


Ps.:

>Oh. Mann.
>Literatur, Literatur, Literatur.
>Online Tutorials sind zuwenig, wenn man in eine Programmiersprache
>neu einsteigt und das die erste Sprache ist.

Kannst du mir irgentwelche Literatur empfelen?

von Karl H. (kbuchegg)


Lesenswert?

Seprendium Diagnostica wrote:
> Hi,
>
> Also. Ich versuche es nochmal. Ich wollte den Wert, den er in diesem
> Textfile in der ersten eile steht, einlesen. Aber bei mir gibt er nur
> True oder False an.

Wovon sprichst du eigentlich?

fgets liest eine Zeile von der Datei ein und speichert das
Vorgefundene in dem, am Aufruf übergebenen, Character Array.

Der Returnwert von fgets ist ein character Pointer. Im Regelfall
ist das der gleiche Pointer, den man als Character Array beim
Aufruf mitgegeben hat. Im Fehlerfall liefert fgets allerdings
einen NULL Pointer. Damit kann man den Returnwert von fgets
direkt in einer if-Abfrage oder einer while-Bedingung verwenden
um die Verarbeitung des gelesenen Strings direkt davon abhängig
zu machen, ob der Lesevorgang geklappt hat, oder ob es dabei
einen Fehler gab.

Da ist nichts mit true oder false.


> True, wenn in dem Textfile etwas dirnsteht, False,
> wenn da nichts drinsteht.

fgets liefert im letzteren Fall einen NULL Pointer um
anzuzeigen, dass nichts gelesen werden konnte.
Wo liegt das Problem?

Du liest eine Zeile von der Datei.
Wenn das nicht geklappt hat, dann -> Fehlermeldung, Festplatte
formatieren oder was auch immer.

Wenn es aber geklappt hat, dann hast du zunächst mal einfach
nur einen String in einem Array.

   if( fgets( line, sizeof( line ), txtfile ) )

ist die kürzere Schreibweise von

   if( fgets( line, sizeof( line ), txtfile ) != NULL )


Und diesen String (der jetzt im Character Array namens 'line'
abgelegt ist) kannst du jetzt bearbeiten, wie du magst.
Unter anderem kann man versuchen, ob man aus diesem String eine
Zahl machen könnte. Zb. mit atoi() oder sscanf() oder einer
Eigenbaufunktion oder ....

> Kannst du mir irgentwelche Literatur empfelen?

Der Klassiker:
Kernighan & Ritchie
Programmieren in C

http://www.amazon.de/s/ref=nb_ss_w?__mk_de_DE=%C5M%C5Z%D5%D1&url=search-alias%3Daps&field-keywords=kernighan

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.