Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Ausgaben in selber Zeile (Konsolenanwendung)


Calculon - Fr 16.02.07 16:23
Titel: Ausgaben in selber Zeile (Konsolenanwendung)
Hi Leute,

ich würde gerne Ausgaben in einer Konsolenanwendung in die selbe Zeile der Konsole schreiben, wobei die alte Ausgabe immer wieder überschrieben werden soll.

Kleines Bsp.:


Delphi-Quelltext
1:
2:
for i := 1 to 100 do
  writeln(i); // <-- i soll immer an der selben Stelle stehen


Kann mir da jemand weiterhelfen?

Gruß

Calculon
--


Leuchtturm - Fr 16.02.07 16:24

Vorher vllt die Zeile löschen :wink: oder soll der vorherige i-Wert auch noch da stehen :?:


Marco D. - Fr 16.02.07 16:26

Ich kenne aus Turbo Pascal den Befehl ClrScr.


Martok - Fr 16.02.07 16:42

Es gibt verschiedene CRT32 Units. Entweder du nimmst so eine, oder du baust dir eine mit WinAPI-Funktionen (was aber Sinnlos ist ;)).
Da hast du dann ein GotoXY, mit dem du den Schreibcursor verschieben kannst.


Calculon - Fr 16.02.07 16:43

Leuchtturm hat folgendes geschrieben:
vorher vllt die Zeile löschen oder soll der vorherige i-Wert auch noch da stehen

Wie Löschen? Wenn ich writeln benutze ordnet delphi sie untereinander an. Bei write nebeneinander. Wenn ich bei write die Ausgabe vorher löschen könnte, könnte das funktionieren.

Marco D. hat folgendes geschrieben:
Ich kenne aus Turbo Pascal den Befehl ClrScr.

Das Problem ist, dass die Ausgabe nicht zwingend in der ersten Zeile stehen muss und ich will nicht den Bildschirm "säubern" müssen.

Noch eine Anmerkung: Die Unit "crt32.pas" bietet den alten GotoXY-Befehl. Ich kann diese Unit aber nicht benutzen, da sie sich nicht mit der anderen Unit, die ich verwende verträgt ("Console32.pas").


Martok - Fr 16.02.07 16:50

user profile iconCalculon hat folgendes geschrieben:
Noch eine Anmerkung: Die Unit "crt32.pas" bietet den alten GotoXY-Befehl. Ich kann diese Unit aber nicht benutzen, da sie sich nicht mit der anderen Unit, die ich verwende verträgt ("Console32.pas").

Dann kopier doch die Funktion nach Console32.pas :)


Calculon - Fr 16.02.07 16:58

Bin ich grad' bei :wink:

Nur jede function oder procedure braucht wieder 'ne andere function oder procedure :roll: ! Ich probier jetzt einfach mal weiter und geb' dann Bescheid.

Gruß

Calculon
--


Calculon - Fr 16.02.07 18:12

Nö, hat nicht funktioniert.

Hier ein Beispielprojekt. Lässt sich zwar kompilieren, bricht aber ab und schließt die Anwendung.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
program Project1;

{$APPTYPE CONSOLE}

uses
  windows, SysUtils;

var
i: integer;
TextAttr: Byte;
ConsoleScreenRect: TSmallRect;
hConsoleOutput: THandle;

function WhereY: Byte;  // aus unit "crt32.pas"
var
  CBI: TConsoleScreenBufferInfo;
begin
  GetConsoleScreenBufferInfo(hConsoleOutput, CBI);
  Result := TCoord(CBI.dwCursorPosition).Y + 1 - ConsoleScreenRect.Top;
end;

procedure DelLine;  // aus unit "crt32.pas"
var
  SourceScreenRect: TSmallRect;
  Coord: TCoord;
  CI: TCharinfo;
  dwSize, dwCount: DWORD;
begin
  SourceScreenRect := ConsoleScreenRect;
  SourceScreenRect.Top := WhereY + ConsoleScreenRect.Top;
  CI.AsciiChar := ' ';
  CI.Attributes := TextAttr;
  Coord.X := SourceScreenRect.Left;
  Coord.Y := SourceScreenRect.Top - 1;
  dwSize := SourceScreenRect.Right - SourceScreenRect.Left + 1;
  ScrollConsoleScreenBuffer(hConsoleOutput, SourceScreenRect, nil, Coord, CI);
  FillConsoleOutputAttribute(hConsoleOutput, TextAttr, dwSize, Coord, dwCount);
end;

procedure GotoXY(X, Y: Byte); // aus unit "crt32.pas"
var
  Coord: TCoord;
begin
  Coord.X := X - 1 + ConsoleScreenRect.Left;
  Coord.Y := Y - 1 + ConsoleScreenRect.Top;
  if not SetConsoleCursorPosition(hConsoleOutput, Coord) then
  begin
    GotoXY(11);
    DelLine;
  end;
end;

begin
for i := 1 to 100 do
  begin
    write(i);
    sleep(1000);
    gotoxy(1,1);
  end;
end.


Kann es sein, dass der ganze Krimskrams der in der unit "crt32.pas" ganz oben steht wichtig für die procedures und functions ist?


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
{$IfDef VER130}
  {$Define NEW_STYLES}
{$EndIf}

{$IfDef VER140}
  {$Define NEW_STYLES}
{$EndIf}

{$IfDef VER150}
  {$Define NEW_STYLES}
{$EndIf}

{$IfDef VER160}
  {$Define NEW_STYLES}
{$EndIf}

{$IfDef VER170}
  {$Define NEW_STYLES}
{$EndIf}


{$HINTS OFF}


{$Define HARD_CRT}       // Redirect STD_...
{..$Define CRT_EVENT}      // CTRL-C,...
{..$Define MOUSE_IS_USED}  // Handle mouse or not
{..$Define OneByOne}       // Block or byte style write


Wenn ja, wo füge ich den in meinem Projekt ein?

Gruß

Calculon
--


BenBE - Fr 16.02.07 23:52

Sowohl TP7, als auch Delphi unterstützen neben dem WriteLn-Befehl auch ein reines Write zum Ausgeben von Text ...

Für die Positionierung gab es unter QBasic früher Location ... Wie der unter TP7 gleich hieß, weiß ich grad nicht aus'm Kopf ...


Delete - Sa 17.02.07 00:22

das war gotoXY :-)


Calculon - Sa 17.02.07 12:01

das war GotoXY :D


BenBE - Sa 17.02.07 18:14

Ahhh, stimmt ...

user profile iconGrenzgaenger hat folgendes geschrieben:
das war gotoXY :-)

user profile iconCalculon hat folgendes geschrieben:
das war GotoXY :D

Wer von euch, wollte nun jetzt wo die Betonung wie weshalb setzen???


Reinhard Kern - Sa 17.02.07 18:27
Titel: Re: Ausgaben in selber Zeile (Konsolenanwendung)
user profile iconCalculon hat folgendes geschrieben:
Hi Leute,

ich würde gerne Ausgaben in einer Konsolenanwendung in die selbe Zeile der Konsole schreiben, wobei die alte Ausgabe immer wieder überschrieben werden soll.

Kleines Bsp.:


Delphi-Quelltext
1:
2:
for i := 1 to 100 do
  writeln(i); // <-- i soll immer an der selben Stelle stehen


Kann mir da jemand weiterhelfen?

Gruß

Calculon
--


Hallo,

einfachste Möglichkeit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    ');
for i := 1 to 100 do
  begin
  write(#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen
  sleep (500);
  end;
writeln;

(ungetestet, aber so ähnlich funktioniert es)

Bei der verbreiteten Neigung hier im Forum, jedes Problem auf möglichst komplizierte Weise zu lösen, ist so etwas Primitives wahrscheinlich nicht konkurrenzfähig.

Gruss Reinhard


Delete - Sa 17.02.07 18:36

user profile iconReinhard Kern hat folgendes geschrieben:

Hallo,

einfachste Möglichkeit:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    ');
for i := 1 to 100 do
  begin
  write(#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen
  sleep (500);
  end;
writeln;

(ungetestet, aber so ähnlich funktioniert es)

Bei der verbreiteten Neigung hier im Forum, jedes Problem auf möglichst komplizierte Weise zu lösen, ist so etwas Primitives wahrscheinlich nicht konkurrenzfähig.

Gruss Reinhard


denke besser wär hier:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    ');
for i := 1 to 100 do
  begin
  write(#13#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen
  sleep (500);
  end;
writeln;


'n schöner CR im write, damit es sich nicht fortsetzt ... ;-)


BenBE - Sa 17.02.07 19:35

Man sollte Source, den man anmeckert bitte auch verstanden haben ...
user profile iconGrenzgaenger hat folgendes geschrieben:
denke besser wär hier:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    ');
for i := 1 to 100 do
  begin
  write(#13#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen
  sleep (500);
  end;
writeln;


'n schöner CR im write, damit es sich nicht fortsetzt ... ;-)

Der Source ohne CR ist nämlich richtig ... Wobei ich die Nutzung von Steuerzeichen nicht als elegantere Lösung ansehe ...


Delete - Sa 17.02.07 23:39

user profile iconBenBE hat folgendes geschrieben:
Man sollte Source, den man anmeckert bitte auch verstanden haben ...
user profile iconGrenzgaenger hat folgendes geschrieben:
denke besser wär hier:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    ');
for i := 1 to 100 do
  begin
  write(#13#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen
  sleep (500);
  end;
writeln;


'n schöner CR im write, damit es sich nicht fortsetzt ... ;-)

Der Source ohne CR ist nämlich richtig ... Wobei ich die Nutzung von Steuerzeichen nicht als elegantere Lösung ansehe ...


das kompliment geb ich gern zurück. schon mal den code getestet??? bei mir funktionierts in beiden fällen. dies nur zu info.
und das write(#13'blablabla'); funktioniert auch, problemslos. dafür ist ja das CR da, um die zeile wieder von vorne zu beginnen... ;-)


Reinhard Kern - So 18.02.07 17:35

user profile iconGrenzgaenger hat folgendes geschrieben:

...
das kompliment geb ich gern zurück. schon mal den code getestet??? bei mir funktionierts in beiden fällen. dies nur zu info.
und das write(#13'blablabla'); funktioniert auch, problemslos. dafür ist ja das CR da, um die zeile wieder von vorne zu beginnen... ;-)


Mein Gott, natürlich ohne CR, sonst bräuchte man ja die Backspaces nicht. So wie zuerst geschrieben funktioniert es nämlich an jeder beliebigen Stelle in der Zeile, solange man soviele BS ausgibt wie die Ausgabe lang war. Man wird doch wohl noch eine Technik verständlich machen können, die erheblich älter ist als der PC, oder ist es wirklich einfach zu einfach?

Gruss Reinhard


Calculon - Mo 19.02.07 18:21

BenBE hat folgendes geschrieben:
Wer von euch, wollte nun jetzt wo die Betonung wie weshalb setzen???

Ich mutmaße mal, dass Grenzgaenger das GotoXY betont hat, weil vor deinem Post bereits die Rede davon war. Ich habe das war betont, weil Gotoxy das Äquvalent zum Basic-Befehl locate (Locomotive Basic) ist, das du erwähnt hast und das leider nicht mehr von Delphi unterstützt wird. Deshalb war! :wink:

Reinhard Kern hat folgendes geschrieben:
Bei der verbreiteten Neigung hier im Forum, jedes Problem auf möglichst komplizierte Weise zu lösen, ist so etwas Primitives wahrscheinlich nicht konkurrenzfähig.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    '); 
for i := 1 to 100 do 
  begin 
  write(#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen 
  sleep (500); 
  end
writeln;

Ist echt voll simpel und danke für den Hinweis! Ich wusste nicht, dass das so geht!

Schönen Dank und Gruß

Calculon
--


BenBE - Mo 19.02.07 23:09

user profile iconCalculon hat folgendes geschrieben:
Reinhard Kern hat folgendes geschrieben:
Bei der verbreiteten Neigung hier im Forum, jedes Problem auf möglichst komplizierte Weise zu lösen, ist so etwas Primitives wahrscheinlich nicht konkurrenzfähig.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    '); 
for i := 1 to 100 do 
  begin 
  write(#8,#8,#8,#8,i:4); // <-- i soll immer an der selben Stelle stehen 
  sleep (500); 
  end
writeln;

Ist echt voll simpel und danke für den Hinweis! Ich wusste nicht, dass das so geht!

Noch einfacher geht es, wenn man 3 Kommas löscht und das hier nimmt :P

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
write ('    '); 
for i := 1 to 100 do 
begin 
  write(#8#8#8#8,i:4); // <-- i soll immer an der selben Stelle stehen 
  sleep (500); 
end
writeln;

Das veranlasst Delphi nämlich sogar dzu, 3 Parameter weniger einzeln als String auszugeben, wodurch die Ausgabe maßgeblich beschleunigt wird :wink:


AlexSs - So 02.11.08 22:49

Hi, hatte in etwa dasselbe Problem. Mit der Crt32 klappt das. Habe da mal alles raus gelöscht, was man nicht unbedingt braucht. Hänge die Datei mal hier an. Du musst dann einmal in deinem Programm das hier ändern:

uses SysUtils;

in

uses Sysutils,ClearWindow;

und dann an richtiger Stelle, also da, wo die bisherige Ausgabe gelöscht werden soll, einfach den Befehl "clrscr" eintragen. Sollte dann funktionieren.
Wichtig!!!!: Speichere die Unit, die hier im Anhang ist, im selben Ordner wie dein Programm. Sollte dann eigentlich funktionieren.

MfG
Alex