MATLAB string 2 number of table - string

I have a 3-year data in a string tableformat.txt. Three of its lines are given below:
12-13 Jan -10.5
14-15 Jan -9.992
15-16 Jan -8
How to change the 3rd column (-10.5, -9.992 and -8) of string to be (-10.500, -9.992 and -8.000) of number?
I have made the following script:
clear all; clc;
filename='tableformat.txt';
fid = fopen(filename);
N = 3;
for i = [1:N]
line = fgetl(fid)
a = line(10:12);
na = str2num(a);
ma(i) = na;
end
ma
which gives:
ma = -1 -9 -8
When I did this change: a = line(10:15);, I got:
Error message: Index exceeds matrix dimensions.

This will work for you.
clear all;
clc;
filename='tableformat.txt';
filename2='tableformat2.txt';
fid = fopen(filename);
fid2 = fopen(filename2,'w');
formatSpec = '%s %s %6.4f\n';
N = 3;
for row = [1:N]
line = fgetl(fid);
a = strsplit(line,' ');
a{3}=cellfun(#str2num,a(3));
fprintf(fid2, formatSpec,a{1,:});
end
fclose(fid);
fclose(fid2);

Related

Use regexprep with cell array for colons to format

I have a cell array formatted as:
t = {'23:34:22.959511';
'22:34:11.885113';
'12:34:08.995146';
'11:34:02.383092'}
I am trying to format the output as 4 column vectors as:
a = 23
22
12
11
b = 34
34
34
34
c = 22
11
08
02
d = 959511
885113
995146
383092
I am using regexprep to operate on the data:
a = regexprep(t,':34:22.959511', '')
However this only pertains to only one string in the data set and not all strings.
How do I divide the string into 4 column vectors -- using regexprep for colon: and display the output below?
If you're willing to use other solutions that regexp: strplit can split on any desired character:
a = zeros(numel(t),1);
b = zeros(numel(t),1);
c = zeros(numel(t),1);
d = zeros(numel(t),1);
for ii = 1:numel(t)
C = strsplit(t{ii}, ':');
a(ii) = str2double(C{1});
b(ii) = str2double(C{2});
tmp = strsplit(C{3},'.'); % Additional split for dot
c(ii) = str2double(tmp{1});
d(ii) = str2double(tmp{2});
end
Of course this only works when your data always has this structure (two colons, then one dot)
Here's a way:
r = cell2mat(cellfun(#str2double, regexp(t, ':|\.', 'split'), 'uniformoutput', false));
This gives
r =
23 34 22 959511
22 34 11 885113
12 34 8 995146
11 34 2 383092
If you really need four separate variables, you can use:
r = num2cell(r,1);
[a, b, c, d] = r{:};
I would recommend using split instead of strsplit. split will operate on vectors and if you use the string datatype you can just call double on the string to get the numeric value
>> profFunc
Adriaan's Solution: 5.299892
Luis Mendo's Solution: 3.449811
My Solution: 0.094535
function profFunc()
n = 1e4; % Loop to get measurable timings
t = ["23:34:22.959511";
"22:34:11.885113";
"12:34:08.995146";
"11:34:02.383092"];
tic
for i = 1:n
a = zeros(numel(t),1);
b = zeros(numel(t),1);
c = zeros(numel(t),1);
d = zeros(numel(t),1);
for ii = 1:numel(t)
C = strsplit(t{ii}, ':');
a(ii) = str2double(C{1});
b(ii) = str2double(C{2});
tmp = strsplit(C{3},'.'); % Additional split for dot
c(ii) = str2double(tmp{1});
d(ii) = str2double(tmp{2});
end
end
fprintf('Adriaan''s Solution: %f\n',toc);
tic
for i = 1:n
r = cell2mat(cellfun(#str2double, regexp(t, ':|\.', 'split'), 'uniformoutput', false));
r = num2cell(r,1);
[a, b, c, d] = r{:};
end
fprintf('Luis Mendo''s Solution: %f\n',toc);
tic
for i = 1:n
x = split(t,[":" "."]);
x = double(x);
a = x(:,1);
b = x(:,2);
c = x(:,3);
d = x(:,4);
end
fprintf('My Solution: %f\n',toc);

python pyparsing scanString - wrong start/end location

I'm trying to find the start and end location of a typical token in a text with the scanString function.
text = """
P: INT;
timer2.et == 3423
Q : INT ;
TIME1: TIME;
TIME2: TIME;
TIMER_Q3 : BOOL;
WECHSEL : BOOL;
m : BOOL;
timer.q = 4
"""
From this text I want to find the location of the XXX.et and the XXX.q tokens:
import pyparsing as pp
TK_TIMER_Q_ET = pp.Word(pp.alphanums + "_") + (pp.Literal(".q") | pp.Literal(".et"))
t_end = []
t_match = []
t_start = []
for match, start, end in TK_TIMER_Q_ET.scanString(text):
t_match.append(match)
t_start.append(start)
t_end.append(end)
i = len(t_match) - 1
k = 0
while k <= i:
print("t_end=", t_end[k])
print("t_start=", t_start[k])
print("t_match=", t_match[k])
print("match=", text[t_start[k]:t_end[k]])
k += 1
As an output I expect "timer2.et" and "timer.q" when I print "match=...", but I get:
t_end= 35
t_start= 26
t_match= ['timer2', '.et']
match= 423
Q
t_end= 189
t_start= 182
t_match= ['timer', '.q']
match=
Would be awesome if somebody could help me with that issue!
What you are missing is the grouping of the characters to make one identifier. Try changing the code the following way:
K_TIMER_Q_ET = pp.Group(pp.Word(pp.alphanums + "_") + (pp.Literal(".q") | pp.Literal(".et")))
Works for me:
('t_end=', 27)
('t_start=', 18)
('t_match=', ([(['timer2', '.et'], {})], {}))
('match=', 'timer2.et')
('t_end=', 153)
('t_start=', 146)
('t_match=', ([(['timer', '.q'], {})], {}))
('match=', 'timer.q')

Read Hex file and append string matlab

I am reading H.264 bitstream as Hex file in matlab. I want to insert some string whenever some certain condition met. Like in the attached image if hex value of 00 00 00 01 occurs anywhere in the file i want to add some string like ABC before 00 00 00 01 in the file. String comparison is easy but how to do a Hex comparison?
Here is my code of reading file as hex file
f = fopen(theFile);
if f==-1
return
end
c = fread(f);
theSize=prod(size((c)));
c=sprintf('%02x\n',c);
c(3:3:end)='';
m=floor(length(c)/nChars);
hex='';
hex=reshape(c(1:m*nChars),nChars,m)';
if mod(length(c),nChars)
hex=strvcat(hex,c(m*nChars+1:end));
end
More specifically i want this c code converted into matlab
QByteArray data, basePattern;
basePattern.resize(3);
//start code:
basePattern[0] = (char) 0x00;
basePattern[1] = (char) 0x00;
basePattern[2] = (char) 0x01;
char end1 = 0x25, end2 = 0x45, end3 = 0x65;
x = myfile;//read using fopen
if (x == end1 || x == end2 {
}
Hex values are really just integers:
x = uint8(hex2dec({'01', '02', '0A', '0B', '25', '45', '65', '00', '01', 'AA'}))
x =
1
2
10
11
37
69
101
0
1
170
And they can be compared directly:
x(3) == uint8(hex2dec('0a'))
ans =
1
So putting it all together, you should create a new buffer and search through the bytes for the pattern, if it's found, insert you data, if not found, just append the byte:
pat0 = uint8(hex2dec('00'));
pat1 = uint8(hex2dec('00'));
pat2 = uint8(hex2dec('01'));
pos = 1;
data = % the uint8 array read in from the file.
new_data = uint8([]);
while pos < length(data) - 2
if data(pos+0) == pat0 && data(pos+1) == pat1 && data(pos+2) == pat2
% insert new data buffer and append pattern
new_data = [new_data my_data_to_insert pat0 pat1 pat2];
pos = pos + 3;
else
% append
new_data = [new_data data(pos)];
pos = pos + 1;
end
end
% append last 2 bytes
new_data = [new_data data(end-1:end)];

Compare to string of names

I am trying to compare the names of two strings, and trying to pick out the name that are not included in the other string.
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
but it keeps returning the entire string as result, the main string contain roughly 1000 names, the images name contain about 300 names, so it should return about 700 names in result but it keep returning all 1000 names.
I tried your code with small vectors:
main = ['aaa' 'bbb' 'ccc' 'ddd'];
image = ['bbb' 'ddd'];
name_size_main = size(main,2);
name_size_image = size(image,2);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result(h) = main_name;
h = h+1;
end
end
I get result = 'aaaccc', is it not what you want to get?
EDIT:
If you are using cell arrays, you should change the line result(h) = main_name; to result{h} = main_name; like that:
main = {'aaa' 'bbb' 'ccc' 'ddd'};
image = {'bbb' 'ddd'};
name_size_main = size(main,2);
name_size_image = size(image,2);
result = cell(0);
h = 1;
for i = 1:name_size_main
checker = 0;
main_name = main(i);
for j = 1:name_size_image
image_name = image(j);
temp = strcmpi(image_name, main_name);
if temp == 1;
checker = temp;
end
end
if checker == 0
result{h} = main_name;
h = h+1;
end
end
You can use cells of string along with setdiff or setxor.
A = cellstr(('a':'t')') % a cell of string, 'a' to 't'
B = cellstr(('f':'z')') % 'f' to 'z'
C1 = setdiff(A,B,'rows') % gives 'a' to 'e'
C2 = setdiff(B,A,'rows') % gives 'u' to 'z'
C3 = setxor(A,B,'rows') % gives 'a' to 'e' and 'u' to 'z'

Separate chars of a file in matlab

I have strings of 32 chars in a file (multiple lines).
What I want to do is to make a new file and put them there by making columns of 4 chars each.
For example I have:
00000000000FDAD000DFD00ASD00
00000000000FDAD000DFD00ASD00
00000000000FDAD000DFD00ASD00
....
and in the new file, I want them to appear like this:
0000 0000 000F DAD0 00DF D00A SD00
0000 0000 000F DAD0 00DF D00A SD00
Can you anybody help me? I am working for hours now and I can't find the solution.
First, open the input file and read the lines as strings:
infid = fopen(infilename, 'r');
C = textscan(infid, '%s', 'delimiter', '');
fclose(infid);
Then use regexprep to split the string into space-delimited groups of 4 characters:
C = regexprep(C{:}, '(.{4})(?!$)', '$1 ');
Lastly, write the modified lines to the output file:
outfid = fopen(outfilename, 'w');
fprintf(outfid, '%s\n', C{:});
fclose(outfid);
Note that this solution is robust enough to work on lines of variable length.
Import
fid = fopen('test.txt');
txt = textscan(fid,'%s');
fclose(fid);
Transform into a M by 28 char array, transpose and reshape to have a 4 char block on each column. Then add to the bottom a row of blanks and reshape back. Store each line in a cell.
txt = reshape(char(txt{:})',4,[]);
txt = cellstr(reshape([txt; repmat(' ',1,size(txt,2))],35,[])')
Write each cell/line to new file
fid = fopen('test2.txt','w');
fprintf(fid,'%s\r\n',txt{:});
fclose(fid);
Here's one way to do it in Matlab:
% read in file
fid = fopen('data10.txt');
data = textscan(fid,'%s');
fclose(fid);
% save new file
s = size(data{1});
newFid = fopen('newFile.txt','wt');
for t = 1:s(1) % format and save each row
line = data{1}{t};
newLine = '';
index = 1;
for k = 1:7 % seven sets of 4 characters
count = 0;
while count < 4
newLine(end + 1) = line(index);
index = index + 1;
count = count + 1;
end
newLine(end + 1) = ' ';
end
fprintf(newFid, '%s\n', newLine);
end
fclose(newFid);

Resources