How to trim white spaces at the end of a string in Marie? - string

Hi I'm new to Marie programming language and I have a string with the address NameAddr.
My print subroutine stops printing when it reaches a 0 character (marking the end of the string).So to trim the white spaces I simply iterate backwards from the address of the last character and as long as its a white space I replace it with a 0.
However, my removeSpace subroutine does not terminate and when I step through it its not updating the LastCharAddr properly after I pass in the address of the last character?
//Remove spaces
LastCharAddr, HEX 0
RemoveSpace, HEX 0
Space, DEC 32 //constant needed for subroutine
CharacterReplace, Hex 000 //constant for subroutine
StartRemoveSpace, LoadI LastCharAddr
Subt Space
Skipcond 400 //If its a space
JumpI RemoveSpace //if not a space terminate
Load CharacterReplace //replace with 0
Store LastCharAddr //Replace
Load LastCharAddr
Subt One// iterate backwards
Store LastCharAddr
Jump StartRemoveSpace
Any help will be appreciated thanks!

Related

How to trim string in MARIE?

Hi I'm new to Marie assembly language.
I'm trying to trim the white spaces at the end of a string. I have a print subroutine that stops printing once it reaches a 0 character so to trim the string at the ends I iterate to the end of the string, get the address of the last character and iterate backwards replacing any white spaces.
My problem is HOW to replace the white spaces because if I replace it in my trim string address I can't iterate backwards correctly? Because it loads value from address 0 instead? Any help will be appreciated.
StartRemoveSpace, LoadI TrimStringAddr //get last char that's not zero
Subt Space
Skipcond 400 //if its a space skip next line
JumpI TrimString //terminate trimming
Load CharacterReplace //replace with 0
//Replace where??
//Store TrimStringAddr
Load TrimStringAddr
Subt One // iterate backwards
Store TrimStringAddr
Jump StartRemoveSpace

MIPS: Creating a string from bytes read

I'm reading a string from a buffer, and at some point I need to stop and get the string of what I've read so far and get the size of this string, so let's say I've the string: "StackOverflow" and going to use "v" as my stop point, so I should have something like "StackO" as my result string.
The thing is, to count the size of it, I'm reading byte by byte, so when I get to the stop point, the register $t0 which is counting the size of it should have the value 6 in it. So, how can I create a string that has "Stack0" in it?
Assuming you are using null-terminated strings, you can either a) copy the string to another buffer and add a 0 (null character) after the 6th character, or b) put the 0 in the original buffer after the 6th character, overwriting the ‘v’, if you don’t mind destroying the original string.

How to remove extra spaces in between string, matlab?

I have created a script to convert text to morsecode, and now I want to modify it to include a slash between words.So something like space slash space between morsecode words. I know my loop before the main loop is incorrect and I want to fix it to do as stated before I just really need help Thank You!!!:
...
Word=input('Please enter a word:','s');
...
Code=MC_1;
...
case ' '
Code='/'
otherwise
Valid=0;
end
if Valid
fprintf('%s ',Code);
else
disp('Input has invalid characters!')
break
end
I know you want to write a loop to remove multiple spaces in between words, but the best way to remove white space in your particular problem would be to use regular expressions, specifically with regexprep. Regular expressions are used to search for particular patterns / substrings within a larger string. In this case, what we are trying to find are substrings that consist of more than one whitespace. regexprep finds substrings that match a pattern, and replaces them with another string. In our case, you would search for any substrings within your string that contain at least one more whitespace characters, and replace them with a single whitespace character. Also, I see that you've trimmed both leading and trailing whitespace for the string using strtrim, which is great. Now, all you need to do is callregexprep like so:
Word = regexprep(Word, '\s+', ' ');
\s+ is the regular expression for finding at least one white space character. We then replace this with a single whitespace. As such, supposing we had this string stored in Word:
Word = ' hello how are you ';
Doing a trim of leading and trailing whitespace, then calling regexprep in the way we talked about thus gives:
Word = strtrim(Word);
Word = regexprep(Word, '\s+', ' ')
Word =
hello how are you
As you can see, the leading and trailing white space was removed with strtrim, and the regular expression takes care of the rest of the spaces in between.
However, if you are dead set on using a loop, what you can do is use a logical variable which is set to true when we detect a white space, and then we use this variable and skip other white space characters until we hit a character that isn't a space. We would then place our space, then /, then space, then continue. In other words, do something like this:
Word = strtrim(Word); %// Remove leading and trailing whitespace
space_hit = false; %// Initialize space encountered flag
Word_noSpace = []; %// Will store our new string
for index=1:length(Word) %// For each character in our word
if Word(index) == ' ' %// If we hit a space
if space_hit %// Check to see if we have already hit a space
continue; %// Continue if we have
else
Word_noSpace = [Word_noSpace ' ']; %// If not, add a space, then set the flag
space_hit = true;
end
else
space_hit = false; %// When we finally hit a non-space, set back to false
Word_noSpace = [Word_noSpace Word(index)]; %// Keep appending characters
end
end
Word = Word_noSpace; %// Replace to make compatible with the rest of your code
for Character = Word %// Your code begins here
...
...
What the above code does is that we have an empty string called Word_noSpace that will contain our word with no extra spaces, and those spaces replaced with a single whitespace. The loop goes through each character, and should we encounter a space, we check to see if we have already encountered a space. If we have, just continue on in the loop. If we haven't, then concatenate a whitespace. Once we finally hit a non-space character, we simply just add those characters that are not spaces to this new string. The result will be a string with no extra spaces, and those are replaced with a single white space.
Running the above code after you trim the leading and trailing white space thus gives:
Word =
hello how are you

Finding mean of ascii values in a string MATLAB

The string I am given is as follows:
scrap1 =
a le h
ke fd
zyq b
ner i
You'll notice there are 2 blank spaces indicating a space (ASCII 32) in each row. I need to find the mean ASCII value in each column without taking into account the spaces (32). So first I would convert to with double(scrap1) but then how do I find the mean without taking into account the spaces?
If it's only the ASCII 32 you want to omit:
d = double(scrap1);
result = mean(d(d~=32)); %// logical indexing to remove unwanted value, then mean
You can remove the intermediate spaces in the string with scrap1(scrap1 == ' ') = ''; This replaces any space in the input with an empty string. Then you can do the conversion to double and average the result. See here for other methods.
Probably, you can use regex to find the space and ignore it. "\s"
findSpace = regexp(scrap1, '\s', 'ignore')
% I am not sure about the ignore case, this what comes to my mind. but u can read more about regexp by typying doc regexp.

Array of Strings in Fortran 77

I've a question about Fortran 77 and I've not been able to find a solution.
I'm trying to store an array of strings defined as the following:
character matname(255)*255
Which is an array of 255 strings of length 255.
Later I read the list of names from a file and I set the content of the array like this:
matname(matcount) = mname
EDIT: Actually mname value is hardcoded as mname = 'AIR' of type character*255, it is a parameter of a function matadd() which executes the previous line. But this is only for testing, in the future it will be read from a file.
Later on I want to print it with:
write(*,*) matname(matidx)
But it seems to print all the 255 characters, it prints the string I assigned and a lot of garbage.
So that is my question, how can I know the length of the string stored?
Should I have another array with all the lengths?
And how can I know the length of the string read?
Thanks.
You can use this function to get the length (without blank tail)
integer function strlen(st)
integer i
character st*(*)
i = len(st)
do while (st(i:i) .eq. ' ')
i = i - 1
enddo
strlen = i
return
end
Got from here: http://www.ibiblio.org/pub/languages/fortran/ch2-13.html
PS: When you say: matname(matidx) it gets the whole string(256) chars... so that is your string plus blanks or garbage
The function Timotei posted will give you the length of the string as long as the part of the string you are interested in only contains spaces, which, if you are assigning the values in the program should be true as FORTRAN is supposed to initialize the variables to be empty and for characters that means a space.
However, if you are reading in from a file you might pick up other control characters at the end of the lines (particularly carriage return and/or line feed characters, \r and/or \n depending on your OS). You should also toss those out in the function to get the correct string length. Otherwise you could get some funny print statements as those characters are printed as well.
Here is my version of the function that checks for alternate white space characters at the end besides spaces.
function strlen(st)
integer i,strlen
character st*(*)
i = len(st)
do while ((st(i:i).eq.' ').or.(st(i:i).eq.'\r').or.
+ (st(i:i).eq.'\n').or.(st(i:i).eq.'\t'))
i = i - 1
enddo
strlen = i
return
end
If there are other characters in the "garbage" section this still won't work completely.
Assuming that it does work for your data, however, you can then change your write statement to look like this:
write(*,*) matname(matidx)(1:strlen(matname(matidx)))
and it will print out just the actual string.
As to whether or not you should use another array to hold the lengths of the string, that is up to you. the strlen() function is O(n) whereas looking up the length in a table is O(1). If you find yourself computing the lengths of these static strings often, it may improve performance to compute the length once when they are read in, store them in an array and look them up if you need them. However, if you don't notice the slowdown, I wouldn't worry about it.
Depending on the compiler that you are using, you may be able to use the trim() intrinsic function to remove any leading/trailing spaces from a string, then process it as you normally would, i.e.
character(len=25) :: my_string
my_string = 'AIR'
write (*,*) ':', trim(my_string), ':'
should print :AIR:.
Edit:
Better yet, it looks like there is a len_trim() function that returns the length of a string after it has been trimmed.
intel and Compaq Visual Fortran have the intrinsic function LEN_TRIM(STRING) which returns the length without trailing blanks or spaces.
If you want to suppress leading blanks or spaces, use "Adjust Left" i.e. ADJUSTF(STRING)
In these FORTRANs I also note a useful feature: If you pass a string in to a function or subroutine as an argument, and inside the subroutine it is declared as CHARACTER*(*), then
using the LEN(STRING) function in the subroutine retruns the actual string length passed in, and not the length of the string as declared in the calling program.
Example:
CHARACTER*1000 STRING
.
.
CALL SUBNAM(STRING(1:72)
SUBROUTINE SYBNAM(STRING)
CHARACTER*(*) STRING
LEN(STRING) will be 72, not 1000

Resources