0
votes

(Translated from German to Englisch) I need help in this exercise :

Thread: String processing The user can make simple changes to an input sentence.

conditions

The program displays a menu for the user to select the following action. This is also displayed again after the action has been completed until the user terminates the program (a loop is therefore required).

The menu contains the following items, which should be executed when the specified letter is entered:

A. Enter the sentence

B. Determine the number of words

C. Determine the number of characters that are less than their sequence character

D. Replace all the words in the sentence with their uppercase initials

X. end

If the user enters a different letter, nothing happens or the menu is output again.

If the menu item A is selected, a prompt is issued to enter a set which is read into a string variable. This variable can not be changed by the actions of menu items B, C and D! Possibly. A copy of the set has to be prepared beforehand in another string variable.

In menu point B the number of all words in the block is to be counted. For simplicity, you can assume that there is always one space between two words. At the beginning and end of the sentence there are no spaces. The number of words is output after the calculation (e.g., "The set is 4 words").

If the user executes menu item C, the set is traversed character-by-character, and for each character it is checked whether it is smaller than its trailing character. Here is a simple character comparison (you can also write directly something like '1' <'d'). The number of characters so found is then output (e.g., "13 characters found in the sentence less than the trailing character").

In menu item D, the sentence is traversed and every word contained in it is replaced by its upper-case initial character. The capitalization is of course only made if the first character is a letter, otherwise the character remains unchanged. You can assume that the sentence never starts or ends with a space. Between two words there is always exactly one space and so it should be between the initial letters. For example, from "123 good mood" becomes "1 G L".

It is not permissible here to build up a completely new string piece by piece! Instead, you should work in a loop on a copy of the original sentence with pos, copy, length, delete and insert! It is also forbidden to "gather" the initial characters all at the beginning or end of the string; These should be inserted directly into the string at the position of the corresponding word!

Furthermore, a string can not be accessed at menu point D, because the work with string routines is to be practised explicitly here. Menu items B, C and D may only be selectable if a record has already been entered. Otherwise nothing happens or a fault message is entered when entering B, C or D in the menu and the menu is output again.

Each call to the menu items B, C or D will always work on the original set entered by the user and not on a set that has already been altered by previously executed menu items!

By entering the menu item A again, the entered block can be overwritten by a new one.

With an 'X' the user can terminate the program.

Use wherever it is the predefined string functions and do not write it yourself with difficulty loops, etc.! However, the use of the strreplace or reverseString functions is forbidden!


Here's my work till now, I only have problems with part D:

     program Project2;
        {$APPTYPE CONSOLE}
        {$R *.res}

        uses
        System.SysUtils;

        const
          lz = ' ';

        var
  Satz: string;
  Buchstabe: char;
  i, p, j, zaehler2, index, count: integer;

 writeln('A) Write Sentence');
readln(Satz);

      'D':
        begin
          index := 2;
         insert(lz, Satz, length(Satz)+1);
          count := (pos(lz,Satz));
          repeat
            delete(Satz, index,(count - index));
            index := index + 2;
           count := pos(lz,copy(Satz,index,(length(Satz)-index)))+index-1;
          until  ;
         writeln(uppercase(Satz));
        end
1
This q seems very similar to your stackoverflow.com/questions/44247115/…, but with some added code, which is a better fit with SO. What is it about item D that is causing you difficulty? Usually, students find splitting the input into words to be the difficult part. Most pascal implementations include functions to convert a string to upper or lower case, and using them is trivial. Which pascal implementation are you using? - MartynA
Since that was closed I couldn't add a comment. I have problems with proceeding to delete letters from every word without deleting the first letter, and with ending the "repeat" function - Ahmed Aziz Ayari
I think I figured out how to delete the letters (from second to last) in every word, but I still don't know how to "end" the repeat-function - Ahmed Aziz Ayari
I did it, NB: lz = space : 'D': begin index := 2; insert(lz, Satz, length(Satz) + 1); count := (pos(lz, Satz)); repeat delete(Satz, index, (count - index)); index := index + 2; count := pos(lz, copy(Satz, index, (length(Satz) - index + 1))) + index - 1; until index > count; writeln(uppercase(Satz)); end - Ahmed Aziz Ayari

1 Answers

0
votes

I'm glad you've found your own solution, well done!

While you've been doing that, I've been writing the answer below and, as I have finished it, I thought I'd post it here to show you another way to go about the problem of extracting words from a string. There are dozens of ways of doing that task, but I hope the one I've used is fairly easy to follow.

Maybe the reason you were having a problem with this is that your string-indexing expressions are a bit too complicated. I bet if you come back to your code in 6 months it will take you a while to figure out what it is supposed to be doing and longer to tell whether it is actually doing it. The key to avoiding problems like that is to break your code up into chucks which are easier to follow and easier to test. So instead of just telling you what your repeat condition should be, I'll show you a way which is easier to follow.

The first thing to do is to extract a singe word from the input. So, first thing I've written is a function, ExtractFirstWord which returns the first word in the input string, whether or not the input includes spaces, and also returns a Remainder string which is what is left or the input string after the first word (and any spaces immediately following it have been removed). This is done using some simple while loops which are coded to skip over the leading spaces and then build a string from the non-space characters which follow.

Code

const
    lz = ' ';

  var
    Satz: string;
    FirstWord : String;
    Remainder : String;

function ExtractFirstWord(const InputStr : String; var Remainder : String) : String;
var
  P : Integer;
  WordStart : Integer;
begin
  Result := '';
  P := 1;
  //  The following skips over any spaces at the start of InputStr
  while (P <= Length(InputStr)) and (InputStr[P] = lz) do
    Inc(P);

  //  Now we know where the first word starts
  WordStart := P;

  //  Now we can get the first word, if there is one
  while (P <= Length(InputStr)) and (InputStr[P] <> lz) do
    Inc(P);
  Result := Copy(InputStr, WordStart, P - WordStart);

  Remainder := Copy(InputStr, P, Length(InputStr));
  //  the following is one way to remove spaces at the start of Remainder
  while (Length(Remainder) > 0) and (Remainder[1] = lz) do
    Delete(Remainder, 1, Length(lz));
  //  instead you could do something simlar to the first `while` loop above
end;

begin
  Satz := ' cat dog ';
  repeat
    FirstWord := ExtractFirstWord(Satz, Remainder);
    FirstWord := UpperCase(FirstWord);
    Satz := Remainder;
    writeln('First word: ', FirstWord, ' remainder: ', Remainder);
  until Remainder = '';
  readln;
end.

This particular way of doing it is not an ideal fit with the other requirements specified in your task but should be easily adaptable to them. E.g, the upper-casing of words could be done "in place" on the input string by upper-casing the current character of it in the second While loop.

Btw, if you are using Delphi or Free Pascal/Lazarus, there is a much simpler way of extracting the words from a string. It uses a TStringList. Try looking it up in the online help and have a thing about how you might use it to do the task.