Correct way of using validatestring? - matlab

I am trying to search for hello inside a text file in matlab with the following code:
fid = fopen(filename, 'r');
if (fid == -1)
error('cnt open');
end
i = 0;
while (i == 0)
str = 'hello';
validStrings = fgets(fid);
validStr = validatestring(str,validStrings);
disp(validStr)
if (line == -1)
i = 1;
else
fprintf(1, '%s', line);
end
end
fclose(fid);
Can i not use validStrings in this case? I get error
??? Error using ==> validatestring
Valid strings must be a cell array of strings.

The function expects a cell of strings:
A = cell(100,1); // use a bigger number if you have a large file
while (i == 0)
str = 'hello';
validStrings = fgets(fid);
j = 1;
[A{j} remain] = strtok(validStrings, ' '); //or other delimiter than spaces
while(size(remain,2) ~= 0)
[A{j} remain] = strtok(str, ' ');
j = j+1;
end
validStr = validatestring(str,A);
disp(validStr)
if (line == -1)
i = 1;
else
fprintf(1, '%s', line);
end
end

Related

Why do I get the error “Dimensions of arrays being concatenated are not consistent while creating COMTRADE file for simulink model?

I am using the above code to generate COMTRADE files for different scenarios in the simulink.
but whenever I add a display into the simulation model i get an error saying the following
Caused by:
Dimensions of arrays being concatenated are not consistent.
How to resolve the issue so that i can use the display but at the same time, i want to create the COMTRADE file?
Following is the MATLAB code that i am using
% Create the .dat file
clc
format short
NS1 = size(tout); % to find the number of samples
NS2 = NS1(1,1);
FileName = input('Please enter a file name:', 's');
FN_cfg = [FileName,'.cfg'];
FN_dat = [FileName,'.dat'];
Data =[transpose((1:1:NS2)) tout M];
csvwrite(FN_dat,Data)
unique(tout, 'rows', 'stable');
% Create the .cfg file
Config = {'Simulation',' ' ,'1999' ;
'12', '12A', '0D'};
fileid = fopen(FN_cfg,'w');
for r = 1:size(Config,1)
for c = 1:size(Config,2)
var = eval(('Config{r,c}'));
if size(var,1) == 0
var = ' ';
end
if isnumeric(var) == 1
var = num2str(var);
end
fprintf(fileid,var);
if c ~= size(Config,2)
fprintf(fileid,(','));
end
end
fprintf(fileid, '\n');
end
fclose(fileid);
AC = {'1','Vr',' ',' ','V','1','0','0','-99999','99998','1','1','P';
'2','Vy',' ',' ','V','1','0','0','-99999','99998','1','1','P';
'3','Vb',' ',' ','V','1','0','0','-99999','99998','1','1','P';
'4','Ir',' ',' ','A','1','0','0','-99999','99998','1','1','P';
'5','Iy',' ',' ','A','1','0','0','-99999','99998','1','1','P';
'6','Ib',' ',' ','A','1','0','0','-99999','99998','1','1','P';
'7','Vr',' ',' ','V','1','0','0','-99999','99998','1','1','S';
'8','Vy',' ',' ','V','1','0','0','-99999','99998','1','1','S';
'9','Vb',' ',' ','V','1','0','0','-99999','99998','1','1','S';
'10','Ir',' ',' ','A','1','0','0','-99999','99998','1','1','S';
'11','Iy',' ',' ','A','1','0','0','-99999','99998','1','1','S';
'12','Ib',' ',' ','A','1','0','0','-99999','99998','1','1','S'};
fileid = fopen(FN_cfg,'a');
for r = 1:size(AC,1)
for c = 1:size(AC,2)
var = eval(('AC{r,c}'));
if size(var,1) == 0
var = ' ';
end
if isnumeric(var) == 1
var = num2str(var);
end
fprintf(fileid,(var));
if c ~= size(AC,2)
fprintf(fileid,(','));
end
end
fprintf(fileid, '\n');
end
fprintf(fileid, '50','\n');
fprintf(fileid, '\n1');
fprintf(fileid, '\n20000,');
fprintf(fileid, '%1d',(NS2));
fprintf(fileid, '\n%s', (datestr(now)));
fprintf(fileid, '\n%s', (datestr(now)));
fprintf(fileid, '\nASCII');
fprintf(fileid, '\n1');
fclose(fileid);
disp('COMTRADE GENERATED!')

Simple MATLAB lexer program

I created a simple lexer program from MATLAB code where, when the user types a string, the lexemes in that string are categorized. However, when I enter a string in the command window the identifiers are not getting displayed.
The code is as follows :
function determineLexemes()
j = 0;
prompt = 'Enter string : ';
str = input(prompt);
arr = char(str);
strTwo = '';
display('Symbol Table');
fprintf('Lexeme \t\t Token \n');
k = length(arr);
for i = 1: k
if(arr(i) == '+')
fprintf('+ \t\t ADD_OP \n');
end
if(arr(i) == '-')
fprintf('- \t\t SUB_OP \n');
end
if(arr(i) == '*')
fprintf('* \t\t MULT_OP \n');
end
if(arr(i) == '/')
fprintf('/ \t\t DIV_OP \n');
end
if(arr(i) == '(')
fprintf('( \t\t LEFT_PAREN \n');
end
if(arr(i) == ')')
fprintf(') \t\t RIGHT_PAREN \n');
end
if(arr(i) == '=')
fprintf('= \t\t EQUAL_OP \n');
end
x = str2num(arr(i));
y = isletter(arr(i));
if(y || (isempty(x) ==0))
strTwo = strcat(strTwo,arr(i));
end
if(~ischar(arr(i)) && ~isnumeric(arr(i)))
if(~isspace(arr(i)) && ~isempty(strTwo))
m(j) = strTwo;
if(isNumeric(strTwo(1)) && regexp('.*[a-zA-]+.*'))
disp(strcat('Error. Potential variable (', strTwo, ') whose name starts with digit found'));
strTwo = '';
j = j + 1;
end
if(~(isNumeric(strTwo(1) && regexp('.*[a-zA-]+.*'))))
disp(strcat(m(j), ('\t\t IDENTIFIER')));
strTwo = '';
j = j + 1;
end
end
end
end
end
And the intended output, when '(2a + b)' is entered to the user prompt,is as follows:
However, the output currently does not identify identifiers (i.e. 2a and b in this example).
Any help on this problem is appreciated.
I tried to keep the changes needed by your code to a minimum, but there were quite a number of mistakes (even things like isNumeric instead of isnumeric or a missing argument for the regex function).
Hope you'll be satisfied with this.
function determineLexemes()
j = 1;
prompt = 'Enter string : ';
str = input(prompt);
arr = char(str);
strTwo = '';
display('Symbol Table');
fprintf('Lexeme \t\t Token \n');
k = length(arr);
for i = 1: k
if(arr(i) == '+')
fprintf('+ \t\t ADD_OP \n');
end
if(arr(i) == '-')
fprintf('- \t\t SUB_OP \n');
end
if(arr(i) == '*')
fprintf('* \t\t MULT_OP \n');
end
if(arr(i) == '/')
fprintf('/ \t\t DIV_OP \n');
end
if(arr(i) == '(')
fprintf('( \t\t LEFT_PAREN \n');
end
if(arr(i) == ')')
fprintf(') \t\t RIGHT_PAREN \n');
end
if(arr(i) == '=')
fprintf('= \t\t EQUAL_OP \n');
end
x = str2num(arr(i));
y = isletter(arr(i));
if(y || ~isempty(x))
strTwo = strcat(strTwo,arr(i));
end
if(~isspace(arr(i)) && ~isempty(strTwo))
if(~isempty(str2num(strTwo(1))) && any(regexp(strTwo,'.*[a-zA-]+.*')))
fprintf(strcat('Error. Potential variable (', strTwo, ') whose name starts with digit found \n'));
strTwo = '';
j = j + 1;
else
if isempty(str2num(strTwo(1)))
fprintf(strcat(strTwo, ('\t\t IDENTIFIER \n')));
strTwo = '';
j = j + 1;
end
end
end
end
end

Concatenating numbers in matlab

I am trying to concatenate 0s and 1s in a matrix to form a binary number (as a string).
For example, [1 0 1;0 0 1] should output ['101';'001']
When trying this input however, I get ['1','1'] as a result. Why?
function result = generateBinary(ref_matrix)
[row col] = size(ref_matrix);
result = cell(1,row);
str = '';
for i=1:row
for j = 1:col
n = num2str(ref_matrix(i,j))
str = strcat(str, num2str(ref_matrix(i,j)));
str
result{1,i} = str;
str = '';
end
end
end
The first end is at the wrong place.
function result = generateBinary(ref_matrix)
[row col] = size(ref_matrix);
result = cell(1,row);
str = '';
for i=1:row
for j = 1:col
n = num2str(ref_matrix(i,j))
str = strcat(str, num2str(ref_matrix(i,j)));
str
end
result{1,i} = str;
str = '';
end
As the indent suggests, result{1,i} = str;str = ''; may not be part of the inner loop.

Matlab Muliple delimiter removing during import

I am struggling with a problem and want a easy way around. I have a big array of data where I have some vector values as ( 1.02 1.23 3.32) format. I want it as 1.02 1.23 3.32 in a tabular form. The problem here is that there are two types of delimiter '(' and ')'.
can anyone help in writing a code for this? I have something like this:
filename = 'U.dat';
delimiterIn = '(';
headerlinesIn = 0;
A = textscan(filename,delimiterIn,headerlinesIn);
But one thing is that it only have one delimiter "(" and it does not work either.
Nishant
If your text file looks something like this:
(1 2 3) (4 5 6)
(7 8 9) (10 11 12)
You can read it in as strings and convert it to a cell array of vectors like this:
% read in file
clear all
filename = 'delim.txt';
fid = fopen(filename); %opens file for reading
tline = fgets(fid); %reads in a line
index = 1;
%reads in all lines until the end of the file is reached
while ischar(tline)
data{index} = tline;
tline = fgets(fid);
index = index + 1;
end
fclose(fid); %close file
% convert strings to a cell array of vectors
rowIndex = 1;
colIndex = 1;
outData = {};
innerStr = [];
for aCell = data % for each entry in data
sline = aCell{1,1};
for c = sline % for each charecter in the line
if strcmp(c, '(')
innerStr = [];
elseif strcmp(c, ')')
outData{rowIndex,colIndex} = num2str(innerStr);
colIndex = colIndex + 1;
else
innerStr = [innerStr, c];
end
end
rowIndex = rowIndex + 1;
colIndex = 1;
end
outData

incapsulation of a code inmatlab

my code is
pathname=uigetdir;
filename=uigetfile('*.txt','choose a file name.');
data=importdata(filename);
element= (data.data(:,10));
in_array=element; pattern= [1 3];
locations = cell(1, numel(pattern));
for p = 1:(numel(pattern))
locations{p} = find(in_array == pattern(p));
end
idx2 = [];
for p = 1:numel(locations{1})
start_value = locations{1}(p);
for q = 2:numel(locations)
found = true;
if (~any((start_value + q - 1) == locations{q}))
found = false;
break;
end
end
if (found)
idx2(end + 1) = locations{1}(p);
end
end
[m2,n2]=size(idx2)
res_name= {'one' 'two'};
res=[n n2];
In this code I finding a pattern in one of the column of my data file and counting how many times it's repeated.
I have like 200 files that I want to do the same with them but unfotunatlly I'm stuck.
this is what I have added so far
pathname=uigetdir;
files=dir('*.txt');
for k=1:length(files)
filename=files(k).name;
data(k)=importdata(files(k).name);
element{k}=data(1,k).data(:,20);
in_array=element;pattern= [1 3];
locations = cell(1, numel(pattern));
for p = 1:(numel(pattern))
locations{p} = find(in_array{k}== pattern(p));
end
idx2{k} = [];
how can I continue this code..??
OK, first define this function:
function [inds, indsy] = findPattern(M, pat, dim)
indices = [];
if nargin == 2
dim = 1;
if size(M,1) == 1
dim = 2; end
end
if dim == 1
if numel(pat) > size(M,1)
return; end
for ii = 1:size(M,2)
inds = findPatternCol(M(:,ii), pat);
indices = [indices; repmat(ii,numel(inds),1) inds]%#ok
end
elseif dim == 2
if numel(pat) > size(M,2)
return; end
for ii = 1:size(M,1)
inds = findPatternCol(M(ii,:).', pat);
indices = [indices; inds repmat(ii,numel(inds),1)]%#ok
end
else
end
inds = indices;
if nargout > 1
inds = indices(:,1);
indsy = indices(:,2);
end
end
function indices = findPatternCol(col, pat)
inds = find(col == pat(1));
ii = 1;
prevInds = [];
while ~isempty(inds) && ii<numel(pat) && numel(prevInds)~=numel(inds)
prevInds = inds;
inds = inds(inds+ii<=numel(col) & col(inds+ii)==pat(ii+1));
ii = ii + 1;
end
indices = inds(:);
end
which is decent but probably not the most efficient. If performance becomes a problem, start here with optimizations.
Now loop through each file like so:
pathname = uigetdir;
files = dir('*.txt');
indices = cell(length(files), 1);
for k = 1:length(files)
filename = files(k).name;
data(k) = importdata(files(k).name);
array = data(1,k).data(:,20);
pattern = [1 3];
indices{k} = findPattern(array, pattern);
end
The number of occurrences of the pattern can be found like so:
counts = cellfun(#(x)size(x,1), indices);