Autor Beitrag
Mister Riös
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43

Win XP
Delphi 7, HTML, CSS, PHP, Java
BeitragVerfasst: Mi 20.01.10 22:33 
Hi,
ich habe eine Konsolenanwendung die nach Eingabe eines Satzes das erste Wort aus diesem Satz bestimmen soll. Ich hab zwar schon Lösungen mit Arrays gelesen, würde die aber gerne darauf verzichten, weil ich mit denen noch nie gearbeitet hab.

Also sieht mein Lösungsansatz so aus:
Der Algorithmus liest solange vom ersten Zeichen anfangend die Zeichen nacheinander auszulesen. Wenn ein Leerzeichen kommt bricht der Algorithmus ab, wenn ein Buchstabe kommt wird dieser an das ende eines anderen Strings angehangen. Danach wird dieser String ausgegeben.

Mein Code:
ausblenden 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:
program erstes_wort;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  wort, frage:string;
  i:integer;

begin
  readln(frage);

  i := 1;
  frage := '';
  while frage[i] <> ' ' do
  begin
    wort := wort + frage[i];
    i := i + 1;
  end;                                                                          
  writeln(wort);
 readln;
end.

I ist eine Zählvariable damit das Programm weiß bei welchem Buchstaben es grade ist.
Wort ist das erste Wort.
Frage ist der eingegebene Satz.

Das Problem:
Es gibt zwar keine Compilermeldungen, aber wenn ich im Programm den Satz eingegeben habe und Enter drücke, schließt sich das Programm nur. Hat jemand eine Ahnung was nicht stimmt?

Danke!
trm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 491
Erhaltene Danke: 19

Windows 7x64
Delphi 7
BeitragVerfasst: Mi 20.01.10 22:37 
Huhu :)

Warum setzt Du in Zeile 16 den abgefragten String auf eine Länge von 0 ?
Hidden
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2242
Erhaltene Danke: 55

Win10
VS Code, Delphi 2010 Prof.
BeitragVerfasst: Mi 20.01.10 22:41 
Hi :)

Du setzt Frage ja auch zurück auf '', nachdem du den wert eingelesen hast. Sagt da der Compiler ncihts zu? Etwas wie "Warning: Value assigned to Frage is never used."? Oder hast du Warnungen abgestellt, dass solltest du dann in den Compileroptionen umstellen.

Darüber hinaus solltest du eigentlich bei ''[1] <> ' '? eine Zugriffsverletzung bekommen. Aber das Programm sollte nicht beenden, am Ende steht ja noch ein ReadLn. Merkwürdig :gruebel:

mfG,

_________________
Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 22:44 
Zudem fehlt die Abbruchbedingung, wenn das Ende des Strings erreicht ist. (Was durch die Leerung des Strings hier ja wie schon gesagt wurde sofort der Fall wäre.)
Mister Riös Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43

Win XP
Delphi 7, HTML, CSS, PHP, Java
BeitragVerfasst: Mi 20.01.10 22:48 
:D
Oh shit, da sollte eigentlich "wort" stehen! Peinlich :oops: Ich hab als ich zu schreiben angefangen hab ein bisschen rumgesaut, da muss mir das entgangen sein^^

Tjah, ähm, damit wäre das geklärt, das Programm läuft genau so wie es soll. Ich verstehe zwar nicht ganz warum das Programm sich einfach geschlossen hat aber jetzt klappt alles. Danke!

@Hidden & jaenicke:
Keine Ahnung was ihr meint was da falsch wäre, das Programm läuft jetzt indem ich einfach in Zeile 16 "frage" durch "wort" ausgetauscht habe.
ausblenden 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:
program erstes_wort;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  wort, frage:string;
  i:integer;

begin
  readln(frage);

  i := 1;
  wort := '';
  while frage[i] <> ' ' do
  begin
    wort := wort + frage[i];
    i := i + 1;
  end;
  writeln(wort);
 readln;
end.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 22:50 
Wenn frage aber leer ist, dann greifst du auf nicht existierenden Speicher zu. Denn schließlich ist der String leer und frage[i] = frage[1] existiert nicht...
Ungleich einem Leerzeichen ist es aber trotzdem, so dass die Schleife ggf. trotzdem weiterläuft (gilt auch wenn kein Leerzeichen vorkommt)...
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 20.01.10 22:52 
Wenn der String nun aber keine Leerzeichen enthält, knallt es.
Denn dann kommt deine Schleife nie zum Ende.
Deshalb solltest du die Bedingung noch modifizieren und zusätzlich die Länge des Strings prüfen.
Mister Riös Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43

Win XP
Delphi 7, HTML, CSS, PHP, Java
BeitragVerfasst: Mi 20.01.10 23:01 
Hey, gute Ideen, das werde ich auf jeden Fall berücksichtigen, aber das sollte eigentlich ganz einfach sein mit einer Repeat unti-Schleife.
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Mi 20.01.10 23:03 
geht auch mit ein wenig umbauten mit dem vorhandenen konstrukt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
while i < length(frage) do begin
  if frage[i]' ' then
   {...}
end;


lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
Mister Riös Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43

Win XP
Delphi 7, HTML, CSS, PHP, Java
BeitragVerfasst: Mi 20.01.10 23:11 
user profile iconelundril hat folgendes geschrieben Zum zitierten Posting springen:
geht auch mit ein wenig umbauten mit dem vorhandenen konstrukt

ausblenden Delphi-Quelltext
1:
2:
3:
4:
while i < length(frage) do begin
  if frage[i]' ' then
   {...}
end;


lg elundril


Hmm, aber dann würde der Algorithmus doch bis zum Ende des Satzes laufen und auch den ganzen Satz wieder wieder in "Wort" speichern. Oder meinst du, dass man dann im Else-Zweig der IF-Anweisung irgendwie aus der WHILE-Schleife rausgeht?
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: Mi 20.01.10 23:16 
break ist das zauberwort das man dann verwenden kann. ;) so springt er dann aus einer schleife raus. eventuell gehts auch folgendes wenn man den compilerschalter aktiviert der regelt das bei der ersten bedingung abgebrochen wird:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
while (i < length(frage)) AND (frage[i] <> ' 'do begin
  wort := wort + frage[i];
  inc(i);
end;


lg elundril

_________________
This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
Boldar
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1555
Erhaltene Danke: 70

Win7 Enterprise 64bit, Win XP SP2
Turbo Delphi
BeitragVerfasst: Mi 20.01.10 23:17 
Übrigens, wenn du eine aktuelle Delphi-Version hast (Weiss leider nicht, ab welcher das geht), kannst du auch folgendes schreiben:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
var c: char;
...


for c in satz do
begin
  if word <> ' ' then
  wort := wort + c
  else
  break;
end;
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 20.01.10 23:21 
Was spricht eigentlich dagegen einfach Pos zu benutzen um die Position des Leerzeichens herauszufinden? Dann kannst du dir die ganze Spielerei mit Schleifen sparen...
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
var
  SpacePos: Integer;
begin
  SpacePos := Pos(' ', frage);
  if SpacePos > 0 then
    wort := Copy(frage, 1, Pred(SpacePos))
  else
    WriteLn('Kein Leerzeichen gefunden');
end;


user profile iconBoldar hat folgendes geschrieben Zum zitierten Posting springen:
Übrigens, wenn du eine aktuelle Delphi-Version hast (Weiss leider nicht, ab welcher das geht)
Diese und andere Spracherweiterungen kamen mit Delphi 2006 dazu.
Mister Riös Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 43

Win XP
Delphi 7, HTML, CSS, PHP, Java
BeitragVerfasst: Mi 20.01.10 23:24 
@elundril: Danke, ich glaube so in der Art werde ich das mal versuchen.

@Boldar: Ich hab Delphi 7, also klappt das wahrscheinlich nicht (Es ist auch zu spät um es auszuprobieren);-)

@jeanicke: Keine Ahnung ob das klappen würde, aber mit den Schleifen geht's auch^^
R4Y
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 41



BeitragVerfasst: So 24.01.10 23:24 
ich würde ja auch pos nehmen ^^

ausblenden Delphi-Quelltext
1:
 wort:=leftstr(frage,pos(frage,' '));					


hierbei ist zu beachten, dass man "strutils" in die uses-klausel aufnehmen muss!