Ini file read and write + add new property + matlab [duplicate] - matlab

This question already has an answer here:
Property_value + matlab
(1 answer)
Closed 9 years ago.
How to read and write ini files: I want to add new property to an existing one. I want to write the ini file to temp file and finally add the new property to it. the new property will have head,name,desc, value and layout (like: line 1 & 3)
#---------------
# head
# --------------
[name]% type
# desc
value
fileData = [];
fh = fopen( fileName, 'r' ); % read handle
tname=tempname();
wfh =fopen(tname,'w'); % write handle
line = fgetl(fh);
val = '';
Prop ='';
type = '';
header = '';
desc= '';
while ischar(line)
if strcmpi(line(1),'#') && strcmpi(line(3),'=')
layout = line(2:end);
elseif strcmpi(line(1),'#')&& ~strcmpi(line(3),'=')
header = line(2:end);
else
Prop = regexp(line,{'\[*\w+\]\s*%\s*.*\s*'},'match');
[property data_type] = strtok(Prop,'%')
prop_p = property{1};% property_name
prop_per = regexprep(prop_p,{'\[','\]'},'');
prop = prop_per{1};
Dtype = data_type{1}; % datatype
dtype = strtrim(strrep(Dtype,'%',''));
DATA_type = dtype{1};
end
% How can i define filedname (prop) for the 'layout' and 'header' as they are found in lines before the actual'prop'.
% From command window
% Undefined variable prop.
% Error in ecco2511>add (line 212)
% fileData.(prop{1}).layout = layout;
desc = fgetl(fh); % description
desc = desc(1:end);
line = fgetl(fh);
val = line(1:end);
fileData.(prop).layout = layout;
fileData.(prop).header = header;
fileData.(prop).type = DATA_type;
fileData.(prop).desc = desc;
fileData.(prop).val = val;
line = fgetl(fh); % keep reading
end
if ~isfield( fileData, propName)
fileData.(propName).val = newVal;
fileData.(propName).type = datatype;
fileData.(propName).desc = description;
fileData.(propName).layout = layout;
fileData.(propName).header = header;
else
error ( 'property %s already exists, use set to change its value',propName );
end
fileData = orderfields( fileData );
propNames = fieldnames( fileData );
for ii = 1:numel( propNames )
fprintf(wfh,'%s\r',fileData.(propNames{ii}).layout);
fprintf(wfh,'\n');
fprintf(wfh,'%s\r',fileData.(propNames{ii}).header);
fprintf(wfh,'\n');
fprintf(wfh,'%s\r',fileData.(propNames{ii}).layout);
fprintf(wfh,'\n');
fprintf( wfh, '[%s]%s\r', (propNames{ii}),fileData.(propNames{ii}).type);
fprintf(wfh,'\n');
fprintf( wfh,'#%s\r',fileData.(propNames{ii}).desc);
fprintf(wfh,'\n');
fprintf( wfh,'%s\r',fileData.(propNames{ii}).val);
fprintf(wfh,'\n');
end
fclose(fh);
fclose(wfh);
[status,errmsg]= movefile(tname,fileName,'f');

Sounds like you need INI Config from MATLAB File Exchange. It will allow you to read, write, and modify INI style files. I have used it a number of times and it works quite well.

Related

How to generalize Matlab function?

I have a Matlab function. I need to generalize this function. This code’s aim is to check this IndicMPs are in the TableTemp, if it is there, then we extract relevant age limits, such as: Age_Limite_DC, Age_Limite_IT, Age_Limite_Ch and Transfert_Prime_IT_DC. My idea is to generalize, passing parameters to find out the "Type_pret" is.(May be I'm wrong) Since I'm beginner to Matlab can someone help me to encode a more generic function that can be used in a more general context?
function Structure = optimisation_function()
Data = load('Data.mat');
Structure = Data.Structure;
TableTemp = Data.TableTemp;
Age_Limite_DC = zeros(size(Structure,1),1);
Age_Limite_IT = zeros(size(Structure,1),1);
Age_Limite_CH = zeros(size(Structure,1),1);
Transfert_Prime_IT_DC = zeros(size(Structure,1),1);
for IndexMPAL = 1 : length(Structure.AnneeSouscription)
% Determine Type_Pret (Loan Type)
if ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'A'))
Type_Pret = 'A';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'B'))
Type_Pret = 'B';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'C'))
Type_Pret = 'C';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'D'))
Type_Pret = 'D';
elseif ~isempty(strfind(Structure.Type_Pret{IndexMPAL},'E'))
Type_Pret = 'E';
end
MP_CP = Structure.NomCodeProduit(IndexMPAL);
MP_AnSous = Structure.AnneeSouscription(IndexMPAL);
MP_TypePret = Type_Pret;
IndicCP = strcmp(MP_CP, TableTemp.CodeProduit);
IndicAS = MP_AnSous== TableTemp.AnneeSouscription;
IndicTP = strcmp(MP_TypePret, TableTemp.TypePret);
IndicMP = IndicCP & IndicAS & IndicTP;
if ~any(IndicMP)
Msg = strcat('CodeProduct:',MP_CP{1}, ', Année Souscription:', num2str(MP_AnSous), ', Type Prêt:', MP_TypePret);
error('Error', Msg)
else
Age_Limite_DC(IndexMPAL,1) = TableTemp.Age_Limite_DC(IndicMP,1);
Age_Limite_IT(IndexMPAL,1) = TableTemp.Age_Limite_IT(IndicMP,1);
Age_Limite_CH(IndexMPAL,1) = TableTemp.Age_Limite_CH(IndicMP,1);
Transfert_Prime_IT_DC(IndexMPAL,1)=
TableTemp.Transfert_Prime_IT_DC(IndicMP,1);
end
end
Structure.Age_Limite_DC = Age_Limite_DC;
Structure.Age_Limite_IT = Age_Limite_IT;
Structure.Age_Limite_CH = Age_Limite_CH;
Structure.Transfert_Prime_IT_DC = Transfert_Prime_IT_DC;
end
The if/elseif can be simplified with a cell array:
liststr = {'A','BB','C','D','E'}; % builds a cell array, each cell contains a string
Positive_matches = strfind(liststr,Structure.Type_Pret{IndexMPAL}) % returns a list for each cell of the indices where the element was found (empty if none)
Index = find(~cellfun('isempty', Positive_matches )) % converts the previous list into a logical 0/1 array indicating whether an item was found (1) or not (0)
% if isempty(Index); continue; end % If no index is found, to avoid an error in the next instruction, skips the rest of the code.
Type_Pret = liststr(Index(1));
If the Type_Pret are the same in your list and in Structure? , you can usestrcmp`:
liststr = {'A','B','C','D','E'};
if any(strcmp(Structure.Type_Pret,liststr))
Type_Pret = Structure.Type_Pret
else
% handle error
end
You can also work directly on Structure.Age_Limite_DC without using Age_Limite_DC.

Matlab name assignment

I am trying to decrease some big chucks of matlab code i had from a while ago, and was hoping to get them a bit more "clean".
The VarName2,VarName3,VarName4 ...etc are provide by measured data and i will know what they are always going to be thus i gave me the name A,B ,C , the think i want changed though is the first part of the name, so every time i run the .m file I will use the input('') option
where as fname = 'SWAN' and A, B , C are the second part of the name and they are constant.
fname = input ('enter name')
fname_A = VarName2
fname_B = VarName3
fname_C = VarName4
and want to be getting
SWAN_A = VarName2
SWAN_B = VarName3
SWAN_C = VarName4
thank you
Following your advices I been trying the structure construction
S.name = input ('enter name of the data ".." ==')
S.A = A;
S.A(1,:)=[];
S.B = B;
S.B(1,:)=[];
S.C = C;
S.C(1,:)=[];
S.D = D;
S.D(1,:)=[];
S.E = E;
S.E(1,:)=[];
may i ask if i can also have an input thing command so i can change the name of the structure?
Precede the script with S='west' and then do
'S'.name = input ('enter name of the data ".." ==')
S.A = A;
Here is how I would probably store the information that you are handling:
S.name = input ('enter name')
S.A = VarName2
S.B = VarName3
S.C = VarName4
And if you want to do it a few times:
for t=3:-1:1
S(t).name = input ('enter name')
S(t).A = VarName2
S(t).B = VarName3
S(t).C = VarName4
end
In this way you could now find the struct named 'swan':
idx = strcmpi({S.name},'SWAN')
you can use eval
eval( sprintf('%s_A = VarName2;', fname ) );
eval( sprintf('%s_B = VarName3;', fname ) );
eval( sprintf('%s_C = VarName4;', fname ) );
Note that the use of eval is not recommended.
One alternative option may be to use struct with dynamic field names:
A.( fname ) = VarName2;
B.( fname ) = VarName3;
C.( fname ) = VarName4;
Now you have three structs (A, B and C) with A.SWAN equal to VarName2, B.SWAN equal to VarName3 etc.

how I can read different text files in Matlab

How can I read different text files in Matlab.
Considering that there are 33 txt files and that every one should be processed.
Here is part of my code with the error.
textFilename = cell(1,33);
id = cell(1,33);
for k=1:33;
textFilename{k} = fullfile('C:\Users\Desktop\SentimentCode\textfiles',['file' num2str(k) '.txt']);
id{k} = fopen(textFilename{k},'rt');
str{k} = textscan(id{k},'%s%s');
str(str == '.') = '';
str(str == '_') = '';
str(str == '-') = '';
% Remove numbers from text
T =regexprep(str, '[\d]', ' ');
end
and my error is:
??? Undefined function or method 'eq' for input arguments of type 'cell'.
Error in ==> Untitled9 at 23
str(str == '.') = '';

How to sort property -value pair in alphabetical order with Matlab

I want to add a property-value pair to existing file. In the mean time all the properties should be ordered in alphabetical order. For example :
[Info] % property 1
value 1
[system] % property 2
value 2
How can i add additional property such that all properties will be sorted in alphabetical order. I was able to add property -value pair to the end of the file using
fh = fopen(filename,'a') but i am not able to sort them alphabetically.
so far i tried this as follows but with this one it keeps printing only the new property-value pair . I want to print remaining properties onces it prints the new one.
function [] = myfun(filename ,propName,propvalue)
rfh = fopen(filename,'r');
tname = tempname();
wfh = fopen(tname,'w');
line = fgetl(rfh);
while ischar(line)
if (line(1) == '[') && (line(end) == ']')
property = lower(line(2:end-1)) % from ini file
String2 = property;
String1 = propName;
[sat] = sor(String1,String2)% subfunction
if sat == -1
fprintf(wfh,'[%s]\r\n%s\r\n',propName,propvalue);
else
fprintf(wfh,'%s\r\n',line);
end
else
fprintf(wfh,'%s\r\n',line);
end
line = fgetl(rfh);
end
fclose(rfh);
fclose(wfh);
movefile(tname,filename,'f')
function [sat] = sor(String1,String2)
Index = 1;
while Index < length(String1) && Index < length(String2) && String1(Index) == String2(Index)
Index = Index + 1;
end
% Return the appropriate code
if String1(Index) < String2(Index)
sat= -1
elseif String1(Index) > String2(Index)
sat= +1
else % the characters at this position are equal -- the shorter of the two strings should be "less than"
if length(String1) == length(String2)
sat = 0
elseif length(String1) < length(String2)
sat = -1
else
sat = +1
end
end
Is this a .ini file? You might want to take a look at INIConfig from the MATLAB File Exchange, a set of routines for handling INI files arranged in a convenient class. I haven't used it, but perhaps it might do what you need.
If not, you can always:
Read in the file
Loop through it line by line
When you find a line starting with [ followed by a word alphabetically later than the property you'd like to insert, insert your property and value
Include the remainder of the file
Write the whole file back out again.
How about read the file into a struct?
function fileData = readFileIntoStruct( fileName )
%
% read [property] value pairs file into struct
%
fh = fopen( fileName, 'r' ); % read handle
line = fgetl( fh );
while ischar( line )
% property
tkn = regexp( line, '\[([^\]+)]\]', 'once', 'tokens' );
% read next line for value
val = fgetl( fh );
fileDate.(tkn{1}) = val;
line = fgetl( fh ); % keep reading
end
fclose( fh ); % don't forget to close the file at the end.
Now you have all the data as a struct with properties as fieldnames and values as the field value.
Now you can update a property simply by:
function fileData = updateProperty( fileData, propName, newVal )
if isfield( fileData, propName )
fileData.(propName) = newVal;
else
warning( 'property %s does not exist - please add it first', propName );
end
You can add a property:
function fileData = addProperty( fileData, propName, newVal )
if ~isfield( fileData, propName )
fileData.(propName) = newVal;
else
warning ( 'property %s already exists, use update to change its value', propName );
end
You can sort the properties alphabetically using orderfields:
fileData = orderfields( fileData );
You can write the struct back to file simply using:
function writeDataToFile( newFileName, fileData )
fopen( newFileName , 'w' ); %write handle
propNames = fieldnames( fileData );
for ii = 1:numel( propNames )
fprintf( fh, '[%s]\r\n%s\r\n', propNames{ii}, fileData.(propNames{ii}) );
end
fclose( fh );
Assumptions:
The properties' names are legitimate Matlab field names (see variable naming for details).
The value of each property is always a string.
I did not include any error-checking code in these examples (files not found, wrongly formatted strings, etc.)
I assume the input file is strictly "[prop] val" pairs without any additional comments etc.

How to update txt file in matlab

I want to update a line in a txt file which contains property-values pairs, where a property is between square brackets and its value in the line below. This is an example file: On top of that i want to ignore the comment lines started with '#'. On the other hand what if i want to add comments to the comment line?
#===========================
#===========================
[system]
# comment
programming
#===========================
[information]
#
application
In this example, ´system´ is a property and ´programming´ its value. The same way, ´information´ is another property and ´application´ its value.
I want to call my function with a property-value pair and update the corresponding values in the txt file. Until now I have the following:
fh = fopen(filename,'r');
fh= fopen(filename,'w');
while ~feof
line = fgetl(fh);
if(line(1) == '[') && (line(end) == ']')
value = lower(line(2:end-1));
Then I will compare the 'value' with my input to check if it matches with property. If so I should update the next line with the new input. Finally I have to write to the original file.
For this sample txt how can I update the word 'programming' to 'system information'?
How about
function [] = updateFile( fileName, propName, newProbVal )
%
% update file fileName, replacing the value of propName with newPropVal
%
% all inputs are strings
%
rfh = fopen( fileName, 'r' ); % read handle
tname = tempname(); % temporary file name
wfh = fopen( tname, 'w' );
% read line by line
foundFlag = false;
line = fgetl( rfh );
while ischar(line)
if foundFlag
fprintf( wfh, '%s\r\n', newProbVal );
foundFlag = false;
else
fprintf( wfh, '%s\r\n', line );
end
tks = regexp( line, ['^\[',propName,'\]'] );
foundFlag = ~isempty(tks);
line = fgetl( rfh );
end
fclose( rfh );
fclose( wfh );
movefile( tname, fileName, 'f' ); % rename temp file name