How to convert a numeric variable to a string in MATLAB - matlab

A=rand(10)
B=find(A>98)
How do you have text saying "There were 2 elements found" where the 2 is general i.e. it isn't text, so that if I changed B=find(A>90) it would automatically no longer be 2.

some_number = 2;
text_to_display = sprintf('There were %d elements found',some_number);
disp(text_to_display);
Also, if you wanted to count the number of elements greater than 98 in A, you should one of the following:
numel(find(A>98));
Or
sum(A>98);
sprintf is a very elegant way to display such data and it's quite easy for a person with a C/C++ background to start using it. If you're not comfortable with the format-specifier syntax (check out the link) then you can use:
text_to_display = ['There were ' num2str(some_number) ' elements found'];
But I would recommend sprintf :)

Related

Converting numbers into timestamps (inserting colons at specific places)

I'm using AutoHotkey for this as the code is the most understandable to me. So I have a document with numbers and text, for example like this
120344 text text text
234000 text text
and the desired output is
12:03:44 text text text
23:40:00 text text
I'm sure StrReplace can be used to insert the colons in, but I'm not sure how to specify the position of the colons or ask AHK to 'find' specific strings of 6 digit numbers. Before, I would have highlighted the text I want to apply StrReplace to and then press a hotkey, but I was wondering if there is a more efficient way to do this that doesn't need my interaction. Even just pointing to the relevant functions I would need to look into to do this would be helpful! Thanks so much, I'm still very new to programming.
hfontanez's answer was very helpful in figuring out that for this problem, I had to use a loop and substring function. I'm sure there are much less messy ways to write this code, but this is the final version of what worked for my purposes:
Loop, read, C:\[location of input file]
{
{ If A_LoopReadLine = ;
Continue ; this part is to ignore the blank lines in the file
}
{
one := A_LoopReadLine
x := SubStr(one, 1, 2)
y := SubStr(one, 3, 2)
z := SubStr(one, 5)
two := x . ":" . y . ":" . z
FileAppend, %two%`r`n, C:\[location of output file]
}
}
return
Assuming that the "timestamp" component is always 6 characters long and always at the beginning of the string, this solution should work just fine.
String test = "012345 test test test";
test = test.substring(0, 2) + ":" + test.substring(2, 4) + ":" + test.substring(4, test.length());
This outputs 01:23:45 test test test
Why? Because you are temporarily creating a String object that it's two characters long and then you insert the colon before taking the next pair. Lastly, you append the rest of the String and assign it to whichever String variable you want. Remember, the substring method doesn't modify the String object you are calling the method on. This method returns a "new" String object. Therefore, the variable test is unmodified until the assignment operation kicks in at the end.
Alternatively, you can use a StringBuilder and append each component like this:
StringBuilder sbuff = new StringBuilder();
sbuff.append(test.substring(0,2));
sbuff.append(":");
sbuff.append(test.substring(2,4));
sbuff.append(":");
sbuff.append(test.substring(4,test.length()));
test = sbuff.toString();
You could also use a "fancy" loop to do this, but I think for something this simple, looping is just overkill. Oh, I almost forgot, this should work with both of your test strings because after the last colon insert, the code takes the substring from index position 4 all the way to the end of the string indiscriminately.

Matlab,problem with concatenation in an iteration? How do I fix it?

The problem I have is that it only works partially, but what can I add to make it work?
A2 = [20 4 6 8 5];
A3 = [10 2 3 4 6];
Str=[];
formatSpec = 'P%d (%d,%d)';
for i=1:length(A2)
str = char(sprintf (formatSpec, i, A2(i),A3(i)));
Str=[Str;str];
end
set(handles.text2,'string',Str);
You are not concatenating strings but char-arrays. Thinking it this way, it already answers your question: If you have a two-digit number, the char-array is one element longer than the char-array of a single-digit number... and you cannot concatenate two arrays of different size vertically.
The solution is fairly simple: use actual strings (introduced somewhere around R2016a). Strings are indicated with "" instead of '', which are chars. So replace your charwith string and it works fine. (Even better: provide the formatSpecas ""-string and it sprintf() will return a string right away)
Side note:
BTW, you should always allocate memory if your are looping. That is why the Str has an orange squiggly underline. This is because MATLAB stores arrays in RAM contiguously and has to copy it to a larger section it it outgrows the current one.
So instead of Str=[], write Str = strings(length(A2),1), and index Str(i) = ... in the loop.
Personally, I like num2str more that sprintf but I cannot give a good reason for this, except for that it also works without providing a format.

Using fscanf in MATLAB to read an unknown number of columns

I want to use fscanf for reading a text file containing 4 rows with an unknown number of columns. The newline is represented by two consecutive spaces.
It was suggested that I pass : as the sizeA parameter but it doesn't work.
How can I read in my data?
update: The file format is
String1 String2 String3
10 20 30
a b c
1 2 3
I have to fill 4 arrays, one for each row.
See if this will work for your application.
fid1=fopen('test.txt');
i=1;
check=0;
while check~=1
str=fscanf(fid1,'%s',1);
if strcmp(str,'')~=1;
string(i)={str};
end
i=i+1;
check=strcmp(str,'');
end
fclose(fid1);
X=reshape(string,[],4);
ar1=X(:,1)
ar2=X(:,2)
ar3=X(:,3)
ar4=X(:,4)
Once you have 'ar1','ar2','ar3','ar4' you can parse them however you want.
I have found a solution, i don't know if it is the only one but it works fine:
A=fscanf(fid,'%[^\n] *\n')
B=sscanf(A,'%c ')
Z=fscanf(fid,'%[^\n] *\n')
C=sscanf(Z,'%d')
....
You could use
rawText = getl(fid);
lines = regexp(thisLine,' ','split);
tokens = {};
for ix = 1:numel(lines)
tokens{end+1} = regexp(lines{ix},' ','split'};
end
This will give you a cell array of strings having the row and column shape or your original data.
To read an arbitrary line of text then break it up according the the formating information you have available. My example uses a single space character.
This uses regular expressions to define the separator. Regular expressions powerful but too complex to describe here. See the MATLAB help for regexp and regular expressions.

How to search a text document by position

I need to search a text file that is about 30 lines. I need it to search row by row and grab numbers based on their position in the text file that will remain constant throughout the text file. Currently I need to get the first 2 numbers and then the last 4 numbers of each row. My code now:
FileToOpen = fopen(textfile.txt)
if FileToOpen == -1
disp('Error')
return;
end
while true
msg = fgetl(FileToOpen)
if msg == -1
break;
end
end
I would like to use the fgetl command if possible as I somewhat know that command, but if their is an easier way that will be more than welcome.
This looks like a good start. You should be able to use msg - '0' to get the value of the numbers. For ascii code the digits are placed next to each other in the right order (0,1,2,3,4,5,6,7,8,9). What you do when you subtract with '0' is that you subtract msg with the ascii code of '0'. You will then get the digits as
tmp = msg - '0';
idx = find(tmp>=0 & tmp < 10); % Get the position in the row
val = tmp(idx); % Or tmp(tmp>=0 & tmp < 10) with logical indexing.
I agree that fgetl is probably the best to use for text without specific structure. However, in case you have a special structure of the text you can use that and thus be able to use more effective algorithms.
In case you was actually after finding the absolute position of the digits in the text, you can save the msgLength = msgLength + length(msg) for every iteration and use that to calculate the absolute position of the digits.

Function to split string in matlab and return second number

I have a string and I need two characters to be returned.
I tried with strsplit but the delimiter must be a string and I don't have any delimiters in my string. Instead, I always want to get the second number in my string. The number is always 2 digits.
Example: 001a02.jpg I use the fileparts function to delete the extension of the image (jpg), so I get this string: 001a02
The expected return value is 02
Another example: 001A43a . Return values: 43
Another one: 002A12. Return values: 12
All the filenames are in a matrix 1002x1. Maybe I can use textscan but in the second example, it gives "43a" as a result.
(Just so this question doesn't remain unanswered, here's a possible approach: )
One way to go about this uses splitting with regular expressions (MATLAB's strsplit which you mentioned):
str = '001a02.jpg';
C = strsplit(str,'[a-zA-Z.]','DelimiterType','RegularExpression');
Results in:
C =
'001' '02' ''
In older versions of MATLAB, before strsplit was introduced, similar functionality was achieved using regexp(...,'split').
If you want to learn more about regular expressions (abbreviated as "regex" or "regexp"), there are many online resources (JGI..)
In your case, if you only need to take the 5th and 6th characters from the string you could use:
D = str(5:6);
... and if you want to convert those into numbers you could use:
E = str2double(str(5:6));
If your number is always at a certain position in the string, you can simply index this position.
In the examples you gave, the number is always the 5th and 6th characters in the string.
filename = '002A12';
num = str2num(filename(5:6));
Otherwise, if the formating is more complex, you may want to use a regular expression. There is a similar question matlab - extracting numbers from (odd) string. Modifying the code found there you can do the following
all_num = regexp(filename, '\d+', 'match'); %Find all numbers in the filename
num = str2num(all_num{2}) %Convert second number from str