Brauche Hilfe beim MS-DOS filereader



  • Hallo Leute,

    ich bin neu hier im Forum, sage "Hallo" 🙂 und hoffe, ihr könnt mir helfen.

    Ich bin dabei mir einen filereader für meinen alten Rechner zu bauen( Auf diesem läuft nur MS-DOS 6.22 ^^. Auf diese Weise bringe ich mir selbst am Besten einzelne Schritte im Programmieren bei ). Dafür benutze ich Turbo C++ 3.0. Wie ich eine Datei einlese und im Stil von MORE auf dem Bildschirm ausgebe beherrsche ich mittlerweile :). Nun probiere ich schon seit geschlagenen 3 Monaten den Inhalt einer Textdatei auf dem Bildschirm auf-/abwärts scrollen zu lassen, im Sinne von es werden die ersten 23 Zeilen einer Datei sofort ausgegeben, und beim drücken der Cursortasten scrollt der Inhalt entsprechend eine Zeile auf- bzw abwärts.

    Diese Aufgabe macht mich langsam echt verrückt 😞 ...
    Ich habe eine Methode in einem anderem Forum gefunden, also einen Quelltext, der das Scrollen vorführt, habe diesen ein bisschen modifiziert, allerdings ist jetzt das Einlesen einer kompletten Datei das Problem 😞 .

    Hier einmal der Quelltext(nur ohne Filehandling):

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    #include <dos.h>
    
    #define length(x) ( sizeof (x) / sizeof *(x) )
    
    enum {
      KEY_ESC = 27,
      ARROW_UP = 256 + 72,
      ARROW_DOWN = 256 + 80,
    };
    
    static char *text[] = {
      "Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1 Line 1",
      "Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2 Line 2",
      "Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3 Line 3",
      "Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4 Line 4",
      "Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5 Line 5",
      "Line 6 Line 6 Line 6 Line 6 Line 6 Line 6 Line 6 Line 6 Line 6 Line 6 Line 6",
      "Line 7 Line 7 Line 7 Line 7 Line 7 Line 7 Line 7 Line 7 Line 7 Line 7 Line 7",
      "Line 8 Line 8 Line 8 Line 8 Line 8 Line 8 Line 8 Line 8 Line 8 Line 8 Line 8",
      "Line 9 Line 9 Line 9 Line 9 Line 9 Line 9 Line 9 Line 9 Line 9 Line 9 Line 9",
      "Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10 Line 10",
      "Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11 Line 11",
      "Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12 Line 12",
      "Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13 Line 13",
      "Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14 Line 14",
      "Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15 Line 15",
      "Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16 Line 16",
      "Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17 Line 17",
      "Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18 Line 18",
      "Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19 Line 19",
      "Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20 Line 20",
      "Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21 Line 21",
      "Line 22 Line 22 Line 22 Line 22 Line 22 Line 22 Line 22 Line 22 Line 22",
      "Line 23 Line 23 Line 23 Line 23 Line 23 Line 23 Line 23 Line 23 Line 23",
      "Line 24 Line 24 Line 24 Line 24 Line 24 Line 24 Line 24 Line 24 Line 24",
      "Line 25 Line 25 Line 25 Line 25 Line 25 Line 25 Line 25 Line 25 Line 25",
      "Line 26 Line 26 Line 26 Line 26 Line 26 Line 26 Line 26 Line 26 Line 26",
      "Line 27 Line 27 Line 27 Line 27 Line 27 Line 27 Line 27 Line 27 Line 27",
      "Line 28 Line 28 Line 28 Line 28 Line 28 Line 28 Line 28 Line 28 Line 28",
      "Line 29 Line 29 Line 29 Line 29 Line 29 Line 29 Line 29 Line 29 Line 29",
      "Line 30 Line 30 Line 30 Line 30 Line 30 Line 30 Line 30 Line 30 Line 30",
      "Line 31 Line 31 Line 31 Line 31 Line 31 Line 31 Line 31 Line 31 Line 31",
      "Line 32 Line 32 Line 32 Line 32 Line 32 Line 32 Line 32 Line 32 Line 32",
      "Line 33 Line 33 Line 33 Line 33 Line 33 Line 33 Line 33 Line 33 Line 33",
      "Line 34 Line 34 Line 34 Line 34 Line 34 Line 34 Line 34 Line 34 Line 34",
      "Line 35 Line 35 Line 35 Line 35 Line 35 Line 35 Line 35 Line 35 Line 35",
      "Line 36 Line 36 Line 36 Line 36 Line 36 Line 36 Line 36 Line 36 Line 36",
      "Line 37 Line 37 Line 37 Line 37 Line 37 Line 37 Line 37 Line 37 Line 37",
      "Line 38 Line 38 Line 38 Line 38 Line 38 Line 38 Line 38 Line 38 Line 38",
      "Line 39 Line 39 Line 39 Line 39 Line 39 Line 39 Line 39 Line 39 Line 39",
      "Line 40 Line 40 Line 40 Line 40 Line 40 Line 40 Line 40 Line 40 Line 40",
      "Line 41 Line 41 Line 41 Line 41 Line 41 Line 41 Line 41 Line 41 Line 41",
      "Line 42 Line 42 Line 42 Line 42 Line 42 Line 42 Line 42 Line 42 Line 42",
      "Line 43 Line 43 Line 43 Line 43 Line 43 Line 43 Line 43 Line 43 Line 43",
      "Line 44 Line 44 Line 44 Line 44 Line 44 Line 44 Line 44 Line 44 Line 44",
      "Line 45 Line 45 Line 45 Line 45 Line 45 Line 45 Line 45 Line 45 Line 45",
      "Line 46 Line 46 Line 46 Line 46 Line 46 Line 46 Line 46 Line 46 Line 46",
      "Line 47 Line 47 Line 47 Line 47 Line 47 Line 47 Line 47 Line 47 Line 47",
      "Line 48 Line 48 Line 48 Line 48 Line 48 Line 48 Line 48 Line 48 Line 48",
      "Line 49 Line 49 Line 49 Line 49 Line 49 Line 49 Line 49 Line 49 Line 49",
      "Line 50 Line 50 Line 50 Line 50 Line 50 Line 50 Line 50 Line 50 Line 50"
    };
    
    static int get_code ( void )
    {
      int ch = getch();
    
      if ( ch == 0 || ch == 224 )
        ch = 256 + getch();
    
      return ch;
    }
    
    static void redraw ( int start, int end )
    {
      int i;
      textcolor(15); textbackground(0);
      clrscr();
    
      for ( i = start; i < end; i++ )
        puts ( text[i] );
    }
    
    int main ( void )
    {
    
      int start = 0, end = 24;
      int op = 0;
    
      while ( redraw ( start, end ), ( op = get_code() ) != KEY_ESC ) {
        switch ( op ) {
        case ARROW_UP:
          if ( start <= 0 ) {
    	//end = length ( text );
    	//start = end - 20;
    	start = 0;
          }
          else {
    	--start;
    	--end;
          }
          break;
        case ARROW_DOWN:
          if ( end >= length ( text ) ) {
    	//start = 0;
    	//end = start + 20;
    	end = length(text);
          }
          else {
    	++start;
    	++end;
          }
          break;
        default: break;
        }
      }
    
      return 0;
    }
    

    Nun komme ich einfach auf keine Lösung dafür, wie man nun eine Datei in einem kompletten Stück einliest. Ich habe es mit einem zweidimensionalen Array versucht, aber schon bei dieser Größe 'char A[100][81];' sagt mir der Compiler, das Array ist zu groß 😡 . Ich komme einfach auf keine Lösung zu diesem Problem! 😞
    Ordentliche Beispiele bzw. Quelltexte an denen man sich orientieren kann finde ich nicht( ich suche täglich um die 3 - 4 Stunden ).

    Bitte könnt ihr mir helfen? Ein Link aus einem Forum, in welchem die selbe Frage beantwortet wurde, Methoden mit kleinem Beispiel, wie ich das Problem noch lösen könnte, irgendwie .. 😞

    Vielen Dank euch im Voraus und ich hoffe durch eure Hilfe kriege ich Klarheit, was diese Aufgabe angeht.



  • Von den folgenden Editoren sollten einige mit Quelltext sein:
    http://texteditors.org/cgi-bin/wiki.pl?MsDosEditors

    Hab nix getestet.

    MfG f.-th.



  • Das mach mal lieber erstmal mit einer Biosfunktion, Int 10h Funktion 6 usw.



  • Vielen Danke für eure Antworten 🙂 .

    f.-th. danke für den Link. Ich habe mir den Quelltext zum Editor Calvin gezogen, allerding habe ich sehr schnell gemerkt, dass dieser Quelltext noch zu viel für mein kleines Brain ist, denn ich kann in dem Quelltext echt nichts nachvollziehen.
    😃

    IOCC ich habe es mal mit der BIOSfunktion int 10h versucht. Nur beim Scrollen, sagen wir mal ich habe 24 zeilen Text und ich scrolle einmal nach oben und anschließend wieder runter, dann ist die oberste Zeile vom Text weg. ^^
    Ich mache da bestimmt mindestens einen Fehler, aber ich weiß nicht wo genau.

    Hier ist der Quelltext:

    #include <conio.h>
    #include <dos.h>
    #include <stdio.h>
    
    enum {
      ESC = 27,
      UP = 256 + 72,
      DOWN = 256 + 80,
    };
    
    static int get_key(void)
    {
    	int ch = getch();
    
    	if(ch == 0 || ch == 224)
    		ch = 256 + getch();
    
    	return ch;
    }
    union REGS regs;
    
    void scroll_up(void)
    {
    	regs.h.ah = 6;
    	regs.h.al = 1;
    	regs.h.bh = 0;
    	regs.h.ch = 1;
    	regs.h.cl = 1;
    	regs.h.dh = 25;
    	regs.h.dl = 80;
    
    	int86(0x10,&regs,&regs);
    }
    
    void scroll_down(void)
    {
    	regs.h.ah = 7;
    	regs.h.al = 1;
    	regs.h.bh = 0;
    	regs.h.ch = 1;
    	regs.h.cl = 1;
    	regs.h.dh = 25;
    	regs.h.dl = 80;
    
    	int86(0x10,&regs,&regs);
    }
    
    int main()
    {
    	clrscr();
    	FILE *f;
    	f=fopen("C:\\RAR.TXT","r");
    
    	char *line;
    
    	while(!feof(f))
    	{
    		fgets(line, 80, f);
    		printf("%s",line);
    	}
    	fclose(f);
    
    	getch();
    
    	int key=0;
    
    	while((key = get_key()) != ESC)
    	{
    		switch(key)
    		{
    			case UP:
    				scroll_up(); break;
    
    			case DOWN:
    				scroll_down(); break;
    
    			default: ;break;
    		}
    	}
    	return 0;
    }
    

    Die oberste und unterste Zeile wird immer einfach nur mit Leerzeichen gefüllt..



  • Ist schon länger her. Ist das Beispiel woran ich mich zu erinnern glaube, bei den Beispielen von Turbo C dabei oder hatte ich das irgend wo extern gefunden?

    Sollte etwa so aussehen wie der Turbo-C-Editor allerdings ohne den compilerspezifischen Kram 😉

    Sah etwa so aus:
    http://de.wikipedia.org/wiki/Turbo_Vision

    MfG f.-th.



  • Hey ^^ .. also ich habe auch nochmal alle Beispiele von Turbo C/Turbo C++ aus der dazugehörigen Onlinehilfe nachgeschlagen, allerdings auch da nichts gefunden 😛
    ..

    Und Calvin sah ungefähr so aus oder wie meinst du? Wenn ja dann sollte ich mir den vielleicht mal genauer angucken 😃



  • Für das Scrollen gibt es verschiedene Lösungen.

    DOS musste ja auf die etwa 64k grossen Dateisegmente Rücksicht nehmen.
    Also, wenn der Quelltext da rein passt, einlesen und dann schiebst du halt den Focus rauf oder runter.

    So weit was mir da noch einfällt.

    MfG f.-th.



  • Guten Morgen 🙂
    danke für die Info f.-th.. Mein Problem an der Sache ist nur, dass ich keine Ahnung habe, wie ich den von dir genannten Weg in Code umsetzen kann. 😞

    Ich weiß weder, wie ich eine ganze Datei als Segment einlesen kann, noch wie ich demnach den Fokus bestimme. Also da das mit dem 2D-Array zum Beispiel nicht funktionierte .. -.- , damit wäre das ganze für mich eigentlich kein Problem gewesen. :p

    Wenn ich jetzt zum Beispiel versucht habe, eine Struktur zu benutzen, um eine Datei einzulesen, die wie folgt aussah(nur zum Test, da schon das 2D-Array mit a[100][81] zu 'groß' war)

    typedef struct
    {
        char *line;
    } Inhalt;
    
    Inhalt textfile[2000];
    

    Tat sich nichts.

    Vielen Dank 🙂



  • Für solche Sachen ist die Dynamische Speicherverwaltung da. malloc() und co ist dein Freund.

    Du kannst doch erstmal die Datei durchsuchen und immer die Position eines Zeilenanfangs in einem Array Speichern. (mit ftell() )Dann brauchst du nur noch an die Position zu springen (mit fseek() ) und von da aus die Datei ausgeben.

    Es gibt auch das Speichermodell Huge. Damit kannst du auch Arrays > 64k verwalten.

    PS.: Schau mal ob bei dir unter den Smilies ein Haken vor BBCode in diesem Beitrag deaktiviere steht. Und dann mach ihn weg



  • Hallo und Danke DirkB :),
    habe mich schon die ganze Zeit gefragt, warum der Code bei mir nicht im Kasten dargestellt wird 😃 .

    Kannst du mir vielleicht ein Beispiel im Bezug auf mein Problem geben ?
    Also mit malloc() ...

    Danke dir



  • Turbo_Freak schrieb:

    Ich habe es mit einem zweidimensionalen Array versucht, aber schon bei dieser Größe 'char A[100][81];' sagt mir der Compiler, das Array ist zu groß 😡 . Ich komme einfach auf keine Lösung zu diesem Problem! 😞

    Das kann nicht sein.
    8100 Bytes am Stück sollten selbst für TC3 kein Problem sein.
    Und wie man Textdateien zeilenweise in ein Stringarray schreibt, steht in jedem besseren Beitrag hier und auch bei diversen Suchmaschinen.



  • Habe das jetzt nicht getestet:
    Wie Dirk schon schrieb richtiges Speichermodell wählen/in der IDE einstellen.
    In der IDE nachsehen wie die Speichergrössen voreingestellt sind und entsprechend anpassen. Ohne Gewähr -> Voreinstellung nur 4k?

    MfG f.-th.



  • Hab gerade mal etas im Code von Calvin gestöbert. Bevor man was anzeigen kann muss man erstmal wissen wieviele Zeichen in eine Zeile passen und wieviele Zeilen zu sehen sind.

    Calvin macht das so:

    mov	ah,15		;get current video state
    	int	10h
    	mov	dl,24		;dl = number of rows - 1
    	cmp	al,7
    	je	inv1		;if B/W text card
    	push	ax
    	push	cx
    	mov	ax,1130h		;get number of rows
    	int	10h
    	pop	cx
    	pop	ax
    	cmp	dl,MAXROWS
    

    Und natürlich wird nicht der langsamste Befehl der ANSI Bibliothek verwendet sondern der Text wird direkt in den Videospeicher geschrieben - Speicher dafür braucht man also schonmal nicht allokieren 😉

    mov	word vidseg,0b000h
    

    Wobei ich meinem VGA-Buch entnehme, das ein Farbmonitor im Textmodus
    eigentlich B800h verwendet 😞

    Naja, das wird bedeuten das der vi-Clone (genau wie sein Vorbild) keine
    Farben verwendet...

    Ausserdem ist vi ja nicht gerade für seine Benutzerfreundlichkeit bekannt.

    Eines der massgeblichsten Probleme wird allerdings sein die Zeilenanfänge zu
    verwalten, vor allem wenn man eine Datei "am Stück" einliest. Wie gross sind eigentlich die anzuzeigenden Dateien ? Wenn die nicht in ein Segment passen
    sollten wirds nochmal komplizierter.



  • Ein guter Ansatz wäre eventuell auch dieser Editor mit Quelltext
    für Borland Compiler. Habe ich aber nicht getestet!

    OSPlus Text Editor 2.1.1 (31st March 2005)

    http://www.osplus.co.uk/

    http://www.owenrudge.net/osplus/

    http://sourceforge.net/projects/osplus/files/Text%20Editor/2.1.1/



  • Danke für deine Antwort merano, 🙂
    nun die Datei, mit der ich anfänglich arbeite ist ~65Kb groß. Diese größe reicht auch total aus fürs erste. 😃


Anmelden zum Antworten