Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Hex to Bin -> Falsche eingabe (https://www.delphipraxis.net/162364-hex-bin-falsche-eingabe.html)

Marcel2906 19. Aug 2011 06:39


Hex to Bin -> Falsche eingabe
 
Hey Leute,

ich habe ein Programm geschrieben, dass Hexadezimalzahlen in Dezimalzahlen umrechnet.
Aber ein wichtiges Element bekomme ich nicht hin.
Und zwar bräuchte ich ein Art Befehl, der sagt.

Code:
If c = g bis z then
writeln('Fehler')
beginne von vorne.
gibt es so etwas?

Hier mein Code:

Code:
program HexToDez;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  a,b,d: integer;
  h,c,y: string;
begin

repeat

writeln('Bitte Hexadezimalzahl eingeben:');
readln(h);
a:= 1;
c:= Upcase(h[a]);

if c='A' then
     begin
      d:=10;
      c:=IntToStr(d);
     end;

    if c='B' then
     begin
      d:=11;
      c:=IntToStr(d);
    end;

    if c='C' then
     begin
      d:=12;
      c:=IntToStr(d);
    end;

    if c='D' then
     begin
      d:=13;
      c:=IntToStr(d);
    end;

    if c='E' then
     begin
      d:=14;
      c:=IntToStr(d);
    end;

    if c='F' then
     begin
      d:=15;
      c:=IntToStr(d);
    end;

    d:=StrToInt(c);
    b:=d;


 while a < length(h) do
  begin

  a:=a+1;
  c:=upcase(h[a]);

    if c='A' then
     begin
      d:=10;
      c:=IntToStr(d);
     end;

    if c='B' then
     begin
      d:=11;
      c:=IntToStr(d);
    end;

    if c='C' then
     begin
      d:=12;
      c:=IntToStr(d);
    end;

    if c='D' then
     begin
      d:=13;
      c:=IntToStr(d);
    end;

    if c='E' then
     begin
      d:=14;
      c:=IntToStr(d);
    end;

    if c='F' then
     begin
      d:=15;
      c:=IntToStr(d);
    end;

 d:=StrToInt(c);
 b:=b*16+d;

end;
writeln(b);
writeln('');
writeln('Beenden? [y]');
readln(y);
until y='y';
end.

chaosben 19. Aug 2011 06:44

AW: Code erweitern
 
Welcher Teil ist denn das Problem?
Die Bedingung fürs IF? Oder das "beginn von vorne"?

haentschman 19. Aug 2011 06:52

AW: Code erweitern
 
Moin...
nur im Fehlerfalle "beginne von vorne" oder grundsätzlich. In diesem Falle wie oft ?

Marcel2906 19. Aug 2011 06:54

AW: Code erweitern
 
Also beginne von vorne hab ich keine Idee zu, das andere würde ich so versuchen:

Code:
if c=g..z then
begin
writeln('Fehler')
//beginne von vorne
end;
Nur in diesem Fehlerfall soll er von vorne beginnen, so dass man wieder eine neue Zahl eingeben kann.

KrasserChecker 19. Aug 2011 07:04

AW: Code erweitern
 
Meinst Du sowas hier:
Delphi-Quellcode:
repeat
  writeln('Bitte Hexadezimalzahl eingeben:');
  readln(h);
  a:= 1;
  c:= Upcase(h[a]);
  if not (c in ['0'..'9','A'..'F']) then
    writeln('Fehler');
until c in ['0'..'9','A'..'F'];

Marcel2906 19. Aug 2011 07:12

AW: Code erweitern
 
dann bekomm ich die fehlermedlung:

Zitat:

[DCC Fehler] HexToDez.dpr(20): E2010 Inkompatible Typen: 'string' und 'AnsiChar'
kann ich zu einem repeat auch mehrere untils machen??
Da ich ja schon ein repeat und until in meinem code habe und du noch ein until hinzugefügt hast...

ensaron 19. Aug 2011 08:05

AW: Code erweitern
 
Delphi-Quellcode:
repeat
  EingabeEinlesenUndPruefen;
  writeln('Beenden? [y]');
  readln(y);
until y='y';
Delphi-Quellcode:
procedure EingabeEinlesenUndPruefen;
var
  erfolgreich: Boolean;
  eingabe: string;
  i: Integer;
begin
  erfolgreich := True;
  repeat
    writeln('Bitte Hexadezimalzahl eingeben:');
    readln(eingabe);
    for i := 1 to Length(eingabe) do
    begin
      if not (AnsiChar(eingabe[i]) in ['0'..'9','A'..'F','a'..'f']) then
      begin
        Writeln('Fehlerhafte Eingabe!');
        erfolgreich := False;
        Break;
      end;
    end;
  until erfolgreich;
  WandleHexInDez(eingabe);
end;
Versuch es mal so. Musst nur noch die eigentliche Umwandlung und Ausgabe in eine procedure "WandleHexInDez" packen.

Zitat:

kann ich zu einem repeat auch mehrere untils machen??
Nein.

gammatester 19. Aug 2011 08:13

AW: Code erweitern
 
Deine
Delphi-Quellcode:
erfolgreich
-Logik ist falsch; es sei denn, Du betrachtest aus unerfindlichen Gründen einen Leerstring als gültige Hexzahl.

Marcel2906 19. Aug 2011 08:36

AW: Code erweitern
 
Ich hab es jetzt mal Versucht, aber ich habe vorher noch nie mit 'procedure' gearbeitet, deswegen klappt es auch wahrscheinlich nicht. Hier mein Code:

Code:
program HexToDez;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type

procedure EingabeEinlesenUndPruefen(Sender: HexToDez)
procedure WandleHexInDez(Sender: HexToDez);

var
y: string;

begin
 repeat
  EingabeEinlesenUndPruefen;
  writeln('Beenden? [y]');
  readln(y);
 until y='y';
end;

procedure EingabeEinlesenUndPruefen;
 var
  erfolgreich: Boolean;
  eingabe: string;
  i: Integer;

begin
erfolgreich := True;
 repeat
  writeln('Bitte Hexadezimalzahl eingeben:');
  readln(eingabe);
   for i := 1 to Length(eingabe) do
    begin
     if not (AnsiChar(eingabe[i]) in ['0'..'9','A'..'F','a'..'f']) then
      begin
       Writeln('Fehlerhafte Eingabe!');
       erfolgreich := False;
       Break;
      end;
     end;
 until erfolgreich;
WandleHexInDez(eingabe);
end;

procedure WandleHexInDez;
var
a,b,d: integer;
h,c,y: string;

begin
 writeln('Bitte Hexadezimalzahl eingeben:');
 readln(h);
 a:= 1;
 c:= Upcase(h[a]);

 if c='A' then
  begin
   d:=10;
   c:=IntToStr(d);
  end;

 if c='B' then
  begin
   d:=11;
   c:=IntToStr(d);
  end;

 if c='C' then
  begin
   d:=12;
   c:=IntToStr(d);
  end;

 if c='D' then
  begin
   d:=13;
   c:=IntToStr(d);
  end;

  if c='E' then
   begin
    d:=14;
    c:=IntToStr(d);
   end;

 if c='F' then
  begin
   d:=15;
   c:=IntToStr(d);
  end;

 d:=StrToInt(c);
 b:=d;

 while a < length(h) do
  begin
   a:=a+1;
   c:=upcase(h[a]);

  if c='A' then
   begin
    d:=10;
    c:=IntToStr(d);
   end;

  if c='B' then
   begin
    d:=11;
    c:=IntToStr(d);
   end;

  if c='C' then
   begin
    d:=12;
    c:=IntToStr(d);
   end;

  if c='D' then
   begin
    d:=13;
    c:=IntToStr(d);
   end;

  if c='E' then
   begin
    d:=14;
    c:=IntToStr(d);
   end;

  if c='F' then
   begin
    d:=15;
    c:=IntToStr(d);
   end;

   d:=StrToInt(c);
   b:=b*16+d;
  end;

writeln('');
writeln('Zahl im Dezimalsystem:');
writeln(b);
writeln('');
end;
end.

ensaron 19. Aug 2011 08:44

AW: Code erweitern
 
Ok den Fall einer leeren Eingabe sollte man natürlich noch behandeln.
Und die Initialisierung von "erfolgreich" gehört natürlich in die Schleife, sonst wird nach einer falschen Eingabe keine andere Eingabe mehr als richtig betrachtet.

Delphi-Quellcode:
..
repeat
  erfolgreich := True;
  writeln('Bitte Hexadezimalzahl eingeben:');
  readln(eingabe);
  if not length(eingabe) >= 1 then
    erfolgreich := False;
..

Marcel2906 19. Aug 2011 08:58

AW: Code erweitern
 
Ich habe mein code nochmals überarbeitet.
Nun bekomme ich die Fehlermeldung:

Zitat:

[DCC Fehler] HexToDez.dpr(46): E2034 Zu viele Parameter
zu folgendem abschnitt:

Code:
begin
 repeat
  erfolgreich := True;
  writeln('Bitte Hexadezimalzahl eingeben:');
  readln(h);
   if not length(h) >= 1 then
    erfolgreich := False;

   for i := 1 to Length(h) do
    begin
     if not (AnsiChar(h[i]) in ['0'..'9','A'..'F','a'..'f']) then
      begin
       Writeln('Fehlerhafte Eingabe!');
       erfolgreich := False;
       Break;
      end;
     end;
 until erfolgreich;
WandleHexInDez(h);        //<------hier
end;

Sir Rufo 19. Aug 2011 09:06

AW: Code erweitern
 
Du solltest den Code ein wenig auftrennen, dann wird alles auch nicht so wuselig.

Hier mal eine Vorlage, wo du die Prüfung und Wandlung noch ausformulieren musst:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure Eingabe( var EingabeText : string );
begin

  if EingabeText <> ''
  then
    begin

      Writeln( 'Fehler: ' + EingabeText + ' ist keine Hexadezimalzahl!' );
      Writeln;

    end;

  Writeln( 'Bitte Hexadezimalzahl eingeben:' );
  ReadLn( EingabeText );

end;

function IstHexZahl( const EingabeText : string ) : Boolean;
begin

  // Hier muss noch der Code für die Prüfung rein

  Result := True;
end;

function HexZahlNachInteger( const HexZahl : string ) : Integer;
begin

  // Hier muss noch der Code für die Umwandlung rein

  Result := 0;
end;

procedure Ausgabe( const HexZahl : string; Zahl : Integer );
begin

  Writeln( 'Hex ' + HexZahl + ' ist dezimal ' + IntToStr( Zahl ) );

end;

var
  EingabeText : string;
  Zahl :       Integer;

begin
  try

    EingabeText := '';

    // Eingabe

    repeat

      Eingabe( EingabeText );

    until IstHexZahl( EingabeText ) or ( EingabeText = '' );

    if EingabeText <> ''
    then
      begin

        // Verarbeitung

        Zahl := HexZahlNachInteger( EingabeText );

        // Ausgabe

        Ausgabe( EingabeText, Zahl );

      end;

  except
    on E : Exception do
      Writeln( E.ClassName, ': ', E.Message );
  end;

end.

himitsu 19. Aug 2011 09:24

AW: Code erweitern
 
Zitat:

Zitat von ensaron (Beitrag 1117979)
Delphi-Quellcode:
if not (AnsiChar(eingabe[i]) in ['0'..'9','A'..'F','a'..'f']) then

Davon würde ich dir schnell mal abraten.

Delphi-Quellcode:
var S: String;

S := '4';
if AnsiChar(S[1]) in ['0'..'9'] then
  ShowMessage('jupp ^^');
S := #$1234;
if AnsiChar(S[1]) in ['0'..'9'] then
  ShowMessage('hä? o.O');


S := 'A';
if AnsiChar(S[1]) in ['A'] then
  ShowMessage('jupp ^^');
S := '&#44353;';
if AnsiChar(S[1]) in ['A'] then
  ShowMessage('hä? o.O');
// aka
S := #$0041;
if AnsiChar(S[1]) in [#$41] then
  ShowMessage('jupp ^^');
S := #$AD41;
if AnsiChar(S[1]) in [#$41] then
  ShowMessage('hä? o.O');
Den Hinweis, den Delphi dir, bei Verwendung von IN, gibt, sollte man beachten. :angle2:
(es sei denn, man prüft auch noch, ob dieses Char sich wirklich in einem passenden "ANSI"-bereich befindet)


PS: entweder "erfolgreich" oder Break ... Beides ist hier etwas übertrieben/nutzlos.

Luckie 19. Aug 2011 09:38

AW: Code erweitern
 
Bitte gebe deinem ersten Beitrag einen aussagekräftigen Titel.

ensaron 19. Aug 2011 10:10

AW: Code erweitern
 
Zitat:

Zitat von himitsu (Beitrag 1118000)

Den Hinweis, den Delphi dir, bei Verwendung von IN, gibt, sollte man beachten. :angle2:
(es sei denn, man prüft auch noch, ob dieses Char sich wirklich in einem passenden "ANSI"-bereich befindet)

Hinweis? Da gabs bei mir keinen.
Was wäre denn die bessere Variante?

PS: Das Break ist natürlich nicht notwendig, aber ich finds schöner, die Überprüfung der Eingabe abzubrechen, nachdem das erste ungültige Zeichen entdeckt wurde.

himitsu 19. Aug 2011 10:52

AW: Hex to Bin -> Falsche eingabe
 
Zitat:

Zitat von ensaron (Beitrag 1118013)
PS: Das Break ist natürlich nicht notwendig, aber ich finds schöner, die Überprüfung der Eingabe abzubrechen, nachdem das erste ungültige Zeichen entdeckt wurde.

Ich sagte ja "entweder oder".
- man kann die Schleife mit Break verlassen
- oder sie endet über die Until/While-Bedingung
Und da hier Bedingung und Break das Selbe machen, ist Eines überflüssig.

Ich wäre sehr überrascht, wenn hier keine Meldung kommen würde:
Delphi-Quellcode:
if not (eingabe[i] in ['0'..'9','A'..'F','a'..'f']) then

ensaron 19. Aug 2011 11:13

AW: Hex to Bin -> Falsche eingabe
 
Ich hab in der Repeat..Until-Schleife ja noch eine For-Schleife drin, die Zeichen für Zeichen über die Eingabe drübergeht. Mit dem Break spring ich auf der For-Schleife, nicht aus der Repeat-Schleife, raus.

Zitat:

Zitat von himitsu (Beitrag 1118023)
Ich wäre sehr überrascht, wenn hier keine Meldung kommen würde:
Delphi-Quellcode:
if not (eingabe[i] in ['0'..'9','A'..'F','a'..'f']) then

Anbei ein Screenshot-Beweis ^^ Und nein, den hab ich nicht gefälscht ^^

EDIT: Aaah du meinst, wenn ich das "AnsiChar" rausnehme - Ja dann bekomm ich ne Warnung, dass ich lieber "CharInSet" verwenden sollte ^^
Screenshot wieder ausgenommen, da somit irrelevant ^^

himitsu 19. Aug 2011 11:33

AW: Hex to Bin -> Falsche eingabe
 
OK, daß dort noch was mit in der Schleife drinsteht, war nicht zu erkennen.
Demnach bezog ich mich natürlich nur auf die oben gepostete Version :angle2:


Jupp, denn min AnsiChar schneidest so so um die 65.000 weitere Kombinationen einfach weg, bzw. ignosierst sie vergleichst nur das untere Byte, also 256 Möglichkeiten.
Nimmt man aber das obere Byte mit in Bezug, dann gibt es für Jeden AnsiChar-Wert noch 255 weitere Werte, welche eigentlich nicht gemeint waren.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:54 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz