I've got a problem with pascal. I'm learning it at school and because I already use Java, I'm a little bit confused. But that is not exactly why it doesn't work. I am trying to make a simple if (condition) write(this) else write(that) program, that runs in the cmd.
When I try to compile the following code, it says, I have to write a ; instead of else, but that just seems odd.
program Project1;
var max : integer;
var max2 : integer;
begin
writeln('Max: Oh no, I'm an integer');
writeln('Which integer is max supposed to be?');
readln (max);
writeln('Max: I don't want to be a', max);
writeln('Multiply Max');
readln (max2);
if (max = max * max2) then
writeln('NO, I do not want to be a', max);
else
writeln('I think I could live with being a ', max * max2);
readln;
end.
program Project1;
var max : integer;
var max2 : integer;
begin
writeln('Max: Oh no, Im an integer');
writeln('Which integer is max supposed to be?');
readln (max);
writeln('Max: I dont want to be a', max);
writeln('Multiply Max');
readln (max2);
if (max = max * max2) then
writeln('NO, I do not want to be a', max)
else
writeln('I think I could live with being a ', max * max2);
readln;
end.
Problem was with if statement, because if is just one line you don't need to close line with ";" and was problems with string lines, don't use " ' " in middle of string
Try fixing your apostrophes in the writelns, and see if that helps:
Write apostrophe sign in writeln function - Pascal
Related
Inside my data flow pipeline I would like to add a derived column and its datatype is array. I would like to split the existing column with 1000 characters without breaking words. I think we can use regexSplit,
regexSplit(<string to split> : string, <regex expression> : string) => array
But I do not know which regular expression I can use for split the existing column without breaking words.
Please help me to figure it out.
I created a workaround for this and it works fine for me.
filter(split(regexReplace(regexReplace(text, `[\t\n\r]`, ``), `(.{1,1000})(?:\s|$)`, `$1~~`), '~~'), #item !="")
I think, we have a better solution than this.
I wouldn't use a regex for this, but a truncating function like this one, courtesy of TimS:
public static string TruncateAtWord(this string input, int length)
{
if (input == null || input.Length < length)
return input;
int iNextSpace = input.LastIndexOf(" ", length, StringComparison.Ordinal);
return string.Format("{0}…", input.Substring(0, (iNextSpace > 0) ? iNextSpace : length).Trim());
}
Translated into expression functions it would look something* like this.
substring(Input, 1, iif(locate(Input, ' ', 1000) > 0, locate(Input, ' ', 1000) , length(Input)) )
Since you don't have a lastIndexOf available as an expression function, you would have to default to locate, which means that this expression truncates the string at the first space after the 1000th character.
*I don't have an environment where I can test this.
I want to make string "t1", "t2","t3", ...so on.
so I did like this
let i =0;...
(something) -> let z = "t" ^ string_of_int (i+1)
my intention is every time that program enters (something), i increases.
because I have to make new string when program enters (something).
but it had syntax error
What should I do?
If you want to embed an integer as part of a string, use Printf.sprintf:
let make_string i =
Printf.sprintf "t%d" i
You'll have to take care of tht part that generates increasing numbers with something else, like a for loop.
I have the following strings in a long string:
a=b=c=d;
a=b;
a=b=c=d=e=f;
I want to first search for above mentioned pattern (X=Y=...=Z) and then output like the following for each of the above mentioned strings:
a=d;
b=d;
c=d;
a=b;
a=f;
b=f;
c=f;
d=f;
e=f;
In general, I want all the variables to have an equal sign with the last variable on the extreme right of the string. Is there a way I can do it using regexprep in MATLAB. I am able to do it for a fixed length string, but for variable length, I have no idea how to achieve this. Any help is appreciated.
My attempt for the case of two equal signs is as follows:
funstr = regexprep(funstr, '([^;])+\s*=\s*+(\w+)+\s*=\s*([^;])+;', '$1 = $3; \n $2 = $3;\n');
Not a regexp but if you stick to Matlab you can make use of the cellfun function to avoid loop:
str = 'a=b=c=d=e=f;' ; %// input string
list = strsplit(str,'=') ;
strout = cellfun( #(a) [a,'=',list{end}] , list(1:end-1), 'uni', 0).' %'// Horchler simplification of the previous solution below
%// this does the same than above but more convoluted
%// strout = cellfun( #(a,b) cat(2,a,'=',b) , list(1:end-1) , repmat(list(end),1,length(list)-1) , 'uni',0 ).'
Will give you:
strout =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
Note: As Horchler rightly pointed out in comment, although the cellfun instruction allows to compact your code, it is just a disguised loop. Moreover, since it runs on cell, it is notoriously slow. You won't see the difference on such simple inputs, but keep this use when super performances are not a major concern.
Now if you like regex you must like black magic code. If all your strings are in a cell array from the start, there is a way to (over)abuse of the cellfun capabilities to obscure your code do it all in one line.
Consider:
strlist = {
'a=b=c=d;'
'a=b;'
'a=b=c=d=e=f;'
};
Then you can have all your substring with:
strout = cellfun( #(s)cellfun(#(a,b)cat(2,a,'=',b),s(1:end-1),repmat(s(end),1,length(s)-1),'uni',0).' , cellfun(#(s) strsplit(s,'=') , strlist , 'uni',0 ) ,'uni',0)
>> strout{:}
ans =
'a=d;'
'b=d;'
'c=d;'
ans =
'a=b;'
ans =
'a=f;'
'b=f;'
'c=f;'
'd=f;'
'e=f;'
This gives you a 3x1 cell array. One cell for each group of substring. If you want to concatenate them all then simply: strall = cat(2,strout{:});
I haven't had much experience w/ Matlab; but your problem can be solved by a simple string split function.
[parts, m] = strsplit( funstr, {' ', '='}, 'CollapseDelimiters', true )
Now, store the last part of parts; and iterate over parts until that:
len = length( parts )
for i = 1:len-1
print( strcat(parts(i), ' = ', parts(len)) )
end
I do not know what exactly is the print function in matlab. You can update that accordingly.
There isn't a single Regex that you can write that will cover all the cases. As posted on this answer:
https://stackoverflow.com/a/5019658/3393095
However, you have a few alternatives to achieve your final result:
You can get all the values in the line with regexp, pick the last value, then use a for loop iterating throughout the other values to generate the output. The regex to get the values would be this:
matchStr = regexp(str,'([^=;\s]*)','match')
If you want to use regexprep at any means, you should write a pattern generator and a replace expression generator, based on number of '=' in the input string, and pass these as parameters of your regexprep func.
You can forget about Regex and Split the input to generate the output looping throughout the values (similarly to alternative #1) .
I am trying to put an input string into sub-string arrays. The number of data in the input file are less than 10 but unknown. The number of spaces between each data is also unclear.
Example:
Asd B Cwqe21 Ddsw Eww
I am quite novice to Fortran, so I do not know which format I should use. My problem is that I do not know the number of data (here I assumed that there are 5), so how can I make the code work?
I tried the following which did not work:
CHARACTER (LEN=100), DIMENSION(10) :: string
READ (1,*) (string,I=1,10)
It seems that the error I got was because there was no 6th string to read and put into string(6).
I tried using the "Index" to find the space, but since I do not know how many spaces are in the string, it did not help me.
I don't know if this is more or less elegant/efficient than the standard approach in M.S.B's comment, but an interesting alternative.
integer istart,nw
character (len=100) line,wd,words(100)
open(1,file='t.dat')
read(1,'(a)')line
istart=1
nw=0
do while(len(trim(line(istart:))).gt.0)
read(line(istart:),*)wd
istart=istart+index(line(istart:),trim(wd))+len(trim(wd))
nw=nw+1
words(nw)=trim(wd)
enddo
write(*,*)trim(line)
write(*,*)('/',trim(words(k)),k=1,nw),'/'
end
An inefficient approach that is simple to program is to try to read the maximum number of items, and if this fails to successively try to read one fewer items until the read is successful, as shown below:
program xread_strings
integer, parameter :: nw = 10
character (len=1000) :: text
character (len=20) :: words(nw)
integer :: i,ierr,nread
text = "Asd B Cwqe21 Ddsw Eww"
nread = 0
do i=nw,1,-1
read (text,*,iostat=ierr) words(:i)
if (ierr == 0) then
nread = i
exit
end if
end do
if (nread > 0) write (*,*) "read ",nread," words: ",("'"//trim(words(i)) // "' ",i=1,nread)
end program xread_strings
! g95 Output:
! read 5 words: 'Asd' 'B' 'Cwqe21' 'Ddsw' 'Eww'
I am generating a comma separated list of names in a string eg
Mr John Blue, Miss A Green, Mr Posh Hyphenated-Surname, Mr Fred Green, Miss Helen Red, Ms Jean Yellow
I now want to display them in a memo box that will hold 50 characters on each line so that as many names as possible (and their trailing comma) appear on each line.
so the above should look like
Mr John Blue, Miss A Green,
Mr Posh Hyphenated-Surname, Mr Fred Green,
Miss Helen Red, Ms Jean Yellow
I've played with
Memo1.text := WrapText(Mystring,50)
but it broke lines at spaces between forename and surnames and I tried
Memo1.text := WrapText(MyString, slinebreak, ',' ,50)
to force it to break only after a comma but that broke at spaces as well as commas. Both also tended to break at a hyphen and I note from Rob Kennedy's reply to a similar question that embedded quotes cause problems with Wrap() so a name like Mr John O'Donald would cause problems.
I even tried rolling my own function by counting characters and looking for commas but got bogged down in multiple nested IFs (Too embarassed to show the dreadful code for that!)
Can anyone offer any help or code showing how this can be done?
PS
I have looked at
'Word wrap in TMemo at a plus (+) char'
'How do I split a long string into “wrapped” strings?'
'Find a certain word in a string, and then wrap around it'
and other similar posts but none seem to match what I am looking for.
Set Memo1.WordWrap:=False;
There are many solutions, I show here just one.
But take care :
If you are using it with large amounts of data then the execution is quite slow
procedure TForm1.AddTextToMemo(needle,xsSrc:string);
var
xsNew:string;
mposOld,mposNew:integer;
start:byte;
begin
xsNew:=xsSrc;
repeat
repeat
mposOld:=mposNew;
mposNew:=Pos(needle,xsSrc);
if mposNew>0 then xsSrc[mposNew]:='*';
until (mposNew > 50) OR (mposNew = 0);
if mposOld > 0 then begin
if xsNew[1] = ' ' then start := 2 else start := 1;
if mposNew = 0 then mposOld:=Length(xsNew);
Memo1.Lines.Add(copy(xsNew,start,mposOld));
if mposNew = 0 then exit;
xsNew:=copy(xsNew,mposOld+1,Length(xsNew)-mposOld);
xsSrc:=xsNew;
mposNew:=0;
end else xsSrc:='';
until xsSrc = '';
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Clear;
AddTextToMemo(',','Mr John Blue, Miss A Green, Mr Posh Hyphenated-Surname, '+
'Mr Fred Green, Miss Helen Red, Ms Jean Yellow');
end;
UPDATE
if you have a small amount of data here is fast and easy to read.
...
var
Form1: TForm1;
NameList: TStrings;
...
NameList := TStringList.Create;
...
procedure TForm1.AddTextToMemoB(needle,xsSrc:string);
var
xsNew:string;
i:integer;
sumLen:byte;
begin
xsNew:=''; sumLen:=0;
nameList.Text:=StringReplace(xsSrc,needle,needle+#13#10,[rfReplaceAll]);
for i := 0 to nameList.Count - 1 do begin
sumLen:=SumLen+Length(nameList[i]);
if i < nameList.Count - 1 then begin
if (sumLen + Length(nameList[i+1]) > 50) then begin
if xsNew='' then xsNew:=nameList[i];
Memo1.Lines.Add(xsNew);
xsNew:='';
sumLen:=0;
end else if xsNew='' then xsNew:=nameList[i]+nameList[i+1] else
xsNew:=xsNew+nameList[i+1];
end else Memo1.Lines.Add(xsNew);
end; // for
end;
I haven't tested it, but something along the following lines ought to do the trick.
for LCh in S do
begin
case LCh of
',' : //Comma completes a word
begin
LWord := LWord + LCh;
if (LLine <> '') and //Don't wrap if we haven't started a line
((Length(LLine) + Length(LWord)) > ALineLimit) then
begin
//Break the current line if the new word makes it too long
AStrings.Add(LLine);
LLine := '';
end;
if (LLine <> ' ') then LLine := LLine + ' '; //One space between words
LLine := LLine + LWord;
LWord := '';
end;
else
if (LWord = '') and (LCh in [' ', #9]) then
begin
//Ignore whitespace at start of word.
//We'll explicitly add one space when needed.
//This might remove some extraneous spaces.
//Consider it a bonus feature.
end else
begin
LWord := LWord + LCh;
end;
end;
end;
//Add the remainder
if (LLine <> '') and //Don't wrap if we haven't started a line
((Length(LLine) + Length(LWord)) > ALineLimit) then
begin
//Break the current line if the new word makes it too long
AStrings.Add(LLine);
LLine := '';
end;
if (LLine <> ' ') then LLine := LLine + ' '; //One space between words
LLine := LLine + LWord;
AStrings.Add(LLine);
Of course you may have noted the duplication that should be moved to a sub-routine.
Tweak away to your hearts content.