Replacing \n in string with new lines in Matlab - string

I'm trying to merge cell-array of strings delimiting each by new line to one string in Matlab.
Following method merges the strings, but the final string contains \n instead of new lines:
function str = toString(self)
% some not important logic that creates cell array called strings
% ...
str = '';
for i = 1 : 9
str = strcat(str, strings(i), '\n');
end
end
It returns: ' 111\n 111\n 111\n333666444555\n333666444555\n333666444555\n 222\n 222\n 222\n'
When I add str = sprintf(str); before the end of the method, it returns Invalid format error. However when I write to Matlab command window sprintf(' 111\n 111\n 111\n333666444555\n333666444555\n333666444555\n 222\n 222\n 222\n'); it returns formatted string without any errors.
Anyone knows what could be a problem? Why it works in command window but doesn't in .m file?

sprintf will loop over the elements or your cell array:
sprintf('%s\n', strings{:})
The problem with your loop is '\n' is a 2 element char array, but what you want is sprintf('\n')

Related

How can I split a string in an array of strings such that each string is either a predefined array of strings, a variable or a string in Matlab?

I have two predefined arrays, say:
first = ["alpha" "beta"];
second = ["{" "}"];
and I want to create a function which receives a string and splits the string in different string arrays(or cell). Each array(or cell) should contain either a single member of one of the two arrays, a variable that is not a member of the arrays (without including the blank space) or a string. Ex:
Input string:
"alpha{ beta} new {} new2 "This is a string" }"
Output string:
"alpha" "{" "beta" "new" "{" "}" "new2" "This is a string" "}"
Hope it is clear!
Bests,
Stergios
I tried this:
S = "alpha{ beta} new new2 {} new3}";
T = ["alpha","beta", "{","}"];
[X,Y] = strsplit(S,[T " "], 'CollapseDelimiters',false);
X = strtrim(X); % you forgot to mention, that you also want to remove whitespace
X(2,:) = [Y,""];
X(strlength(X)==0) = []
but S does not accept strings of strings and if I use '' every word will be in a different cell!

Lua string manipulation

This is my code
local function char(...) return string.char(...) end
local function addtok(text,token,C)
text = text or ""
local string = ""
local count = 0
for word in text:gmatch(("[^%s]+"):format(char(C))) do
string = string..char(C)..word
end
string = string..char(C)..token
print(string)
end
The function
addtok("Devotion Aura;Charger;Righteous Fury","Seal of Wisdom",59)
returns
";Devotion Aura;Charger;Righteous Fury;Seal of Wisdom"
but what I want is
"Devotion Aura;Charger;Righteous Fury;Seal of Wisdom"
possible fix: print(string.sub(string, 2))
any better solution?
local function addtok(text,token,C)
local string = (text or "").. string.char(C) .. token
print(string)
end
addtok("Devotion Aura;Charger;Righteous Fury","Seal of Wisdom",59)
The line string = string..char(C)..word will prepend the first semicolon. That's the issue with appending within a loop - you have to make an exception for either the last or the first element if you don't want a trailing or leading delimiter. In this case however, you should be using table.concat, both for performance (avoiding unnecessary string copies) and convenience of joining by delimiter:
local function char(...) return string.char(...) end
local function addtok(text,token,C)
text = text or ""
local words = {}
local count = 0
for word in text:gmatch(("[^%s]+"):format(char(C))) do
table.insert(words, word)
end
local string = table.concat(words, char(C))..char(C)..token
print(string)
end

How to break a text block up so that it will display only One Word on each line

I am importing longer form text into a Unity program. I need one word of the longer text to be displayed on each line...
Thanks
The problem with working with large blocks of text in Word is that operations like Find and Replace can only be performed with Find text strings of 255 characters or less without causing an error. Once you import your text and assign it to a string variable, you can use Len() to determine the length of the string and then use Left() Mid() and Right() to breakup the larger string into shorter chunks of 250 characters each. Here's some code I wrote for just a find and replace situation:
With Selection.Find
y = Len(Selection.Text)
Select Case y
Case Is <= 250
x = 1
.Text = stFound
.Execute Replace:=wdReplaceAll
Case Is <= 500
Dim stFound2 As String
x = 2
z = Len(stFound) - 250
stFound1 = Left(stFound, 250)
stFound2 = Right(stFound, z)
Case Is <= 750
Dim stFound2 As String
Dim stFound3 As String
x = 3
stFound1 = Left(stFound, 250)
stFound2 = Mid(stFound, 251, 249)
stFound3 = Right(stFound, Len(stFound) - 500)
End Select
End With
I then used a For Next loop to run a Find and Replace on each string.
In your situation, it's going to be important to not break up the strings in the middle of a word. To do this you can use the InStr() function to find the position of spaces within your string and then break up the text according to where the spaces are. I wouldn't try using the Split() function on the raw text as depending on the size of the string you could run into a Subscript Out of Range error.
Once the text is chunked down into useable pieces, use the Split() function to send each word to an array and then run the following code to put each word on it's own line or paragraph:
Dim stTxt as String
dim stWord as String
dim stArr() as String
dim x as long
stTxt = 'One of your text strings
stArr() = Split(stTxt)
For x = LBound(stArr()) to UBound(stArr())
stWord = stArr(x) & "^p"
Selection.Typetext stWord
Next
After a little more research, I determined that the 255 character limit to text strings only affects some functions, not all. So I took a 17,335 character (including spaces) Word document and ran Split() on it to create an Array. There were no errors and the resulting array had a UBound of 2690.
So the next question is what kind of text is being imported into Word and what size is it. Is it just a list of words separated by spaces, or another delimiter? Does it contain any punctuation? If it's just a list of words separated by spaces or another delimiter such as a comma or semicolon, the Split() function will sort the words into an Array, at least up to 17,000 characters. More testing would be required for a larger text block. If the text contains punctuation, you would have to process the text to remove the unwanted punctuation which can be done with a Wildcard Find and Replace as long as the Find string is <= 255 characters. But if all you have are words and spaces or some other delimiter, using Split() to separate each word into an array element would work and then just run code as in the second half of my previous example:
For x = LBound(stArr()) to UBound(stArr())
stWord = stArr(x) & "^p"
Selection.Typetext stWord
Next

Matlab substring

I am trying to get average a specific value in a long string and cannot figure out how to pull a value out of the middle of the string. I would like to pull out the 27 from this and the other strings and add them
2015-10-1,33,27,20,29,24,20,96,85,70,30.51,30.40,30.13,10,9,4,10,6,,T,5,Snow,35
2015-10-1,33,27,20,29,24,20,96,85,70,30.51,30.40,30.13,10,9,4,10,6,,T,5,Snow,35
2015-10-2,37,32,27,32,27,23,92,80,67,30.35,30.31,30.28,10,10,7,7,4,,T,8,Rain-Snow,19
2015-10-3,39,36,32,35,33,29,100,90,79,30.30,30.17,30.11,10,7,0,8,3,,0.21,8,Fog-Rain,13
2015-10-4,40,37,34,38,36,33,100,96,92,30.23,30.19,30.14,2,1,0,6,0,,0.13,8,Fog-Rain,27
2015-10-5,46,38,30,38,34,30,100,91,61,30.19,30.08,29.93,10,7,0,6,2,,T,6,Fog-Rain,23
fid = fopen('MonthlyHistory.html');
for i=1:2
str = fgets(fid);
c = strsplit(str,',');
mean=mean+c;
end
fprintf('Average Daily Temperature: %d\n',mean);
Method 1: use readtable
I'm guessing this is pulled from weather underground? Take your csv file and make sure it is saved with a .csv ending. Then what I would do is:
my_data = readtable('MonthlyHistory.csv');
This reads the whole file into the highly convenient table variable type. Then you can do:
average_daily_temp = my_data.MeanTemperatureF; %or whatever it is called in the table
I find tables are a super convenient way to keep track of tabular data. (plus readtable is pretty good).
Method 2: continue your approach...
fid = fopen('mh2.csv');
str = fgets(fid); % May need to read off a few lines to get to the
str = fgets(fid); % numbers
my_data = []; %initialize an empty array
while(true)
str = fgets(fid); % read off a line
if(str == -1) % if str is -1, which signifies end of file
break; %exit loop
end
ca = strsplit(str,','); % split string into a cell array of strings
my_data(end+1,:) = str2num(ca{3}); % convert the 3rd element to a number and store it
end
fclose(fid);
Now my_data is an array holding the 3rd element of each line.
You can use textscan, you might be able to simplfy your code using this as well, but for a single string, it works like this:
S='2015-10-1,33,27,20,29,24,20,96,85,70,30.51,30.40,30.13,10,9,4,10,6,,T,5,Snow,35'
T=textscan(S,'%s','Delimiter',',')
str2double(T{1}{3}) %// the value we want is the 3rd field

How do I read a delimited file with strings/numbers with Octave?

I am trying to read a text file containing digits and strings using Octave. The file format is something like this:
A B C
a 10 100
b 20 200
c 30 300
d 40 400
e 50 500
but the delimiter can be space, tab, comma or semicolon. The textread function works fine if the delimiter is space/tab:
[A,B,C] = textread ('test.dat','%s %d %d','headerlines',1)
However it does not work if delimiter is comma/semicolon. I tried to use dklmread:
dlmread ('test.dat',';',1,0)
but it does not work because the first column is a string.
Basically, with textread I can't specify the delimiter and with dlmread I can't specify the format of the first column. Not with the versions of these functions in Octave, at least. Has anybody ever had this problem before?
textread allows you to specify the delimiter-- it honors the property arguments of strread. The following code worked for me:
[A,B,C] = textread( 'test.dat', '%s %d %d' ,'delimiter' , ',' ,1 )
I couldn't find an easy way to do this in Octave currently. You could use fopen() to loop through the file and manually extract the data. I wrote a function that would do this on arbitrary data:
function varargout = coltextread(fname, delim)
% Initialize the variable output argument
varargout = cell(nargout, 1);
% Initialize elements of the cell array to nested cell arrays
% This syntax is due to {:} producing a comma-separated
[varargout{:}] = deal(cell());
fid = fopen(fname, 'r');
while true
% Get the current line
ln = fgetl(fid);
% Stop if EOF
if ln == -1
break;
endif
% Split the line string into components and parse numbers
elems = strsplit(ln, delim);
nums = str2double(elems);
nans = isnan(nums);
% Special case of all strings (header line)
if all(nans)
continue;
endif
% Find the indices of the NaNs
% (i.e. the indices of the strings in the original data)
idxnans = find(nans);
% Assign each corresponding element in the current line
% into the corresponding cell array of varargout
for i = 1:nargout
% Detect if the current index is a string or a num
if any(ismember(idxnans, i))
varargout{i}{end+1} = elems{i};
else
varargout{i}{end+1} = nums(i);
endif
endfor
endwhile
endfunction
It accepts two arguments: the file name, and the delimiter. The function is governed by the number of return variables that are specified, so, for example, [A B C] = coltextread('data.txt', ';'); will try to parse three different data elements from each row in the file, while A = coltextread('data.txt', ';'); will only parse the first elements. If no return variable is given, then the function won't return anything.
The function ignores rows that have all-strings (e.g. the 'A B C' header). Just remove the if all(nans)... section if you want everything.
By default, the 'columns' are returned as cell arrays, although the numbers within those arrays are actually converted numbers, not strings. If you know that a cell array contains only numbers, then you can easily convert it to a column vector with: cell2mat(A)'.

Resources