i need help replacing the integers in this file.

1 view (last 30 days)
I have a function replaceMultiples that I am trying to write. it is supposed to take an input as a filename (fname) of a text file, and a natural number (num). Where each line of the text file contains one or more integers, separated by a blank space. Go through the text file fname line by line and replaces each integer that is a multiple of num by the integer divided by num. And write the modified text file to a text file with the same name as the original file, but started with ’updated# ’, where # represents the number num. I need it to also display the number of integers that were replaced. For example, if I have a file:
example.txt
123 571 33
14 15 18
6 9
28 25 33 3
An example input:
n=replaceMultiples(example.txt,3) %the value of "n" should equal 8 (the number of integers replaced)
After executing the script the command window should show n=8 and
the new file would appear as "updated3 example.txt " and look like this:
41 571 11
14 5 6
2 3
28 25 11 12
I have this script written so far, but have some problems with it I cannot figure out.
function numReplaced =replaceMultiples(fname, num)
ifh=open(fname,'r'); %open the input file for reading
ofn = sprintf('%s%d%s', 'updated_', num, fname); %creates the output file name
ofn=fopen(ofn, 'wt') %open the output file for writing
numReplaced=n;
n=0;
ln=' '; %initiation of ln
while isnumeric(fname)
ln=fgetl(ifh);
if isnumeric(ln)
while ~isempty(ln)
if strcmp(tk/num=1) %calls integers divisable by num
fprint(ofh,' %s',tk); %write it to the input file
end
fprintf9ofh,'\n');
end
end
end
flcose(ifh);
fclose(ofh);
I am just looking for some help correcting the problems with the script. If you could please give me some ways to improve it I would really appreciate it! Oh and I was told that the functions str2num and num2str would come in handy but I do not have any idea where the functions could be used!

Answers (2)

Walter Roberson
Walter Roberson on 20 Oct 2017
ofn = sprintf('%s%d%s', 'updated_', num, fname);
and fget1 needs to be fgetl (you have the digit 1 instead of lower-case L)
You have
ln=fget1(ifh);
if isnumeric(ln)
However, the only time that isnumeric() will be true for the result of fgetl() is if end of file was encountered. isnumeric does not test to see if the input is a string that represents a number: it tests to see if the input is type single(), double(), int8(), int16(), int32(), int64(), uint8(), uint16(), uint32(), or uint64().
... there are other problems as well.
  2 Comments
Kevin Smith
Kevin Smith on 20 Oct 2017
Okay, I fixed the ones you suggested. What could I use instead of 'isnumeric'? How would you write the while loop?
Walter Roberson
Walter Roberson on 23 Oct 2017
If you have broken out a sequence of characters that you will need to convert to numeric form if it represents a number, and you do not know if the sequence does represent a number, then you can use
num = str2double(ln);
if ~isnan(num)
because nan is always returned by str2double() if the characters do not represent a number.

Sign in to comment.


Stephen23
Stephen23 on 23 Oct 2017
Edited: Stephen23 on 23 Oct 2017
First a few notes:
  • Processing numeric data that is encoded in character arrays is quite inefficient, and makes the code complex: numeric data should be converted to numeric variables, which then makes all numeric operations on those variables much more efficient.
  • Not only is is very inefficient, it also makes it easy to create bugs: your use of isnumeric makes no sense because the variable data type is always going to be character.
  • Using a while loop, if and mod to detect the multiples could work, but it is much simpler and more efficient to use indexing.
  • Depending on the requirements, you might still need to think about trailing space characters and newlines.
  • It is recommended to check the output of fopen, and display the second output if there is any problem opening the file.
Here is a working function which has been tested with your example data:
function replaceMultiples(fname, num)
foutp = sprintf('updated%d %s',num,fname);
[fid,mig] = fopen(fname,'rt');
[fod,mog] = fopen(foutp,'wt');
assert(fid>=3,mig);
assert(fod>=3,mog);
while ~feof(fid)
str = fgetl(fid);
vec = sscanf(str,'%f');
idx = mod(vec,num)==0;
vec(idx) = vec(idx)/num;
fprintf(fod,'%d ',vec);
fprintf(fod,'\n');
end
fclose(fid);
fclose(fod);
end
And tested on your sample data gives this output:
41 571 -11
14 5 6
2 3
28 25 11 12
Both files are attached as well.

Categories

Find more on Characters and Strings in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!