MATLAB Answers

ASSIGNMENT: TEXT FILES Write a function called char_counter that counts the number of a certain character in a text file. The function takes two input arguments, fname, a char vector of the filename and character, the char it counts in the file.

1,850 views (last 30 days)
Rakshith R
Rakshith R on 29 Mar 2019
Commented: Walter Roberson on 10 Jun 2020 at 21:55
When testing with '' your solution returned -1 which is incorrect. (0)
This error pops up while doing the assignment.
can anyone tell me why is this error popping and the meaning of the statement mentioned above.
when the character is ' " ' then i get a finite answer. and when the character is ' ' ' then too answer is a finite number. but i dont understand what the above bold text means....
my code
function charnum = char_counter(fname,character)
fid=fopen(fname);
if fid< 0
charnum = -1;
return;
end
if strcmp(character,'')==1
charnum=0;
return;
end
if double(character)>=35 && double(character)<=43 && double(character) ~=39 && double(character) ~= 41 && double(character) ~= 40
charnum = 0;
return;
end
if double(character) >=60 && double(character) <=64 && double(character) ~= 63
charnum = 0;
return;
end
if double(character) == 81 || double(character) == 88 || double(character) == 90
charnum = 0;
return;
end
cc = fgets(fid);
sumv=0;
while ischar(cc)
z = sprintf('%s',cc);
k = strfind(z,character);
sumv = sumv + length(k);
cc = fgets(fid);
end
charnum = sumv;
if charnum == 0
charnum =-1;
return;
end

  3 Comments

Walter Roberson
Walter Roberson on 29 Mar 2019
Why are you special-casing Q, X, Z ? Why are you special-casing the special characters?
Special-casing '' might be reasonable, but it looks to me as if none of those special cases are needed.
What is wrong is that when no copies of the character are detected, then because the sum will be 0, charnum will be assigned 0, and then your if charnum == 0 will be triggered, causing you to return -1. -1 should only be returned if there is a problem with the input you were given, and if the character simply is not found then the result should be 0.
Rakshith R
Rakshith R on 30 Mar 2019
thanks for clearing this
but when i remove those statement i get a error stating
char_counter('simple.txt',11) failed
why so
Shubham Pandey
Shubham Pandey on 11 Apr 2020
The basic error this code is generating is that when you pass '' as character and if it reads 0 and stores it in charnum, this charnum is getting changed to -1 due to last if block. That is why, the error is showing up. Therefore, it is advisable to remove the last if block. Instead, you may add additional OR condition in the first if block to check for the validity of the character in addition to fid<0.

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 29 Mar 2019
Edited: Walter Roberson on 29 Mar 2019
You are apparently using some kind of automated assignment assessing software. You submitted an assignment for grading. The course software tried passing '' (the empty character vector, equivalent to char([]) ) to your function, and your function returned the value -1 which is not what the assignment specifies should be returned for that input, so it told you that you are wrong.
We do not know what assignment you were doing, or what the correct answer was to that input. You will need to re-read the question more carefully to see what you should have responded with.
I speculate that you were doing the assignment that has been going around about counting the number of matches of a character in a file. The assignment other people have been posting requires that -1 be returned if the input is invalid. I suspect that you are seeing the '' (empty character vector) and considering it to be invalid and so returning -1, but that if you were to read the assignment more carefully you would find that the assignment considers '' to be a valid input and that the number of matches you would expect for it would be 0. Be careful with your validation tests: isempty() is true for both [] and '' .

  0 Comments

Sign in to comment.

More Answers (21)

Kushal Gorti
Kushal Gorti on 30 Apr 2020
I passed all the conditions for the assessment with a very simple code without using any loops. I worked directly on the vectors
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 || ~ischar(character) %checks if the file is valid and if it is a visible character or not using OR operator
charnum=-1;
return;
end
x=fscanf(fid,'%c'); %fscanf scans the entire file and stores it in a column vector x
charnum=length(find(x==character)); %find() finds all the characters that are required and stores the indices in a vector. The length of this vector gives the number of characters
end

AYUSH GURTU
AYUSH GURTU on 28 May 2019
function charnum = char_counter(fname,character)
fid=fopen(fname);
if fid< 0
charnum = -1;
return;
end
if strcmp(character,'')==1
charnum=0;
return;
end
if strcmp(character,' " ')==1
charnum=0;
return;
end
if double(character)>=35 && double(character)<=43 && double(character) ~=39 && double(character) ~= 41 && double(character) ~= 40
charnum = 0;
return;
end
if double(character) >=60 && double(character) <=64 && double(character) ~= 63
charnum = 0;
return;
end
if double(character) == 81 || double(character) == 88 || double(character) == 90
charnum = 0;
return;
end
cc = fgets(fid);
sumv=0;
while ischar(cc)
z = sprintf('%s',cc);
k = strfind(z,character);
sumv = sumv + length(k);
cc = fgets(fid);
end
charnum = sumv;
if ischar(character)==0
charnum =-1;
elseif charnum==0
charnum=0;
return;
end
end

  1 Comment

Walter Roberson
Walter Roberson on 28 May 2019
None of those special cases on double(character) are needed.
if ischar(character) should be tetsed right at the top.
You never close your input file. In particular you do not close it when you return early.
elseif charnum==0
charnum=0;
return;
Why bother? You test for 0 and assign 0 if it is 0, and then you return early but not returning early would just mean proceeding to the next line that is the end of the code.

Sign in to comment.


Mohammed Albattikhi
Mohammed Albattikhi on 2 Jan 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0
charnum = -1;
return
end
if ischar(character) == 0
charnum = -1;
return
end
x=fileread(fname);
n=length(x);
count = 0;
for i=1:n
if(x(i)==character) && ischar(character)
count=count+1;
end
end
charnum = count

  3 Comments

Walter Roberson
Walter Roberson on 31 Mar 2020
In the case that the fopen() works but the second parameter is not character, this leaves the file open when it returns.

Sign in to comment.


Gokul surya Subramanian
Gokul surya Subramanian on 17 Apr 2019
try this...it returns -1 if its not valid...if the character is not found 'sumv=0', it returns charnum=0
if ischar(character)==0
charnum =-1;
elseif charnum==0
charnum=0;
return;
end

  2 Comments

asad jaffar
asad jaffar on 20 Apr 2019
@ Gokul surya subramanian and @ walter robertson ,whats wrong with @Rakshith R code? can you guys help me out ?? i need help ,can you guys guide me .
Walter Roberson
Walter Roberson on 20 Apr 2019
The assignment is specific about when -1 is to be returned: if the file does not exist or the input parameter is not character. When '' is passed then that is character so it is not permitted to return -1 for it. '' cannot be found in the file so the number of times it is found would be 0, so 0 would have to be returned not -1

Sign in to comment.


Mounic Kumar
Mounic Kumar on 25 Jun 2019
try this....
function charnum = char_counter(
fname,A)
fid = fopen(fname,'rt');
if fid < 0
charnum = -1;
return
end
if fid >0 && ischar(A)
k=0;
oneread = fgets(fid);
while ischar(oneread)
k = k + count(oneread,A);
oneread = fgets(fid);
end
charnum = k;
else
charnum = -1;
end
fclose(fid);

Jaimin Motavar
Jaimin Motavar on 2 Jul 2019
can some tell me what is the my mistake in this code?problem is written in comment secssion.
function charnum = char_counter(filename,b)
charnum=0;
if ~ischar(b)
charnum=-1;
return;
end
fid = fopen(filename,'rt');
if fid<0
charnum=-1;
return;
end
oneline= fgets(fid);
while ischar(oneline)
a=sprintf('%s \n',oneline);
c=findstr(b,a);
[m,n]=size(c);
charnum=charnum+n;
oneline=fgets(fid);
end
end

  3 Comments

Sign in to comment.


Ajith Thomas
Ajith Thomas on 19 Aug 2019
Edited: Ajith Thomas on 19 Aug 2019
my question is which all characters should be eliminated? on this question?

  3 Comments

Walter Roberson
Walter Roberson on 19 Aug 2019
There are different versions of the assignment around. In the most common case, there are no characters that should be eliminated. The tests against Q V and so on were hacks to deal code mistakes the user had made.
A common mistake people make is that they are returning -1 when a valid input is not found. They should be returning 0 instead. -1 is reserved for file not found or invalid input argument.
Ajith Thomas
Ajith Thomas on 22 Aug 2019
function charnum=char_count1(fname,a)
fid=fopen(fname,'rt');
if fid<0
charnum=-1;
return;
end
if fid>0 && ischar(a)
line=fgets(fid);
n=0;
while ischar(line)
n=n+count(line,a);
line=fid(line);
end
charnum=n;
else
charnum=-1;
end
fclose(fid);
this will work

Sign in to comment.


Irfan Hussain
Irfan Hussain on 1 Apr 2020
function charnum = char_counter(fname, character)
fid = fopen(fname, 'rt');
if fid < 0
charnum = -1;
elseif ischar(character) == 1
A = char(fread(fid,inf)).';
txt_length = length(A);
counter = 0;
for i = 1: txt_length
if character == A(i);
counter = counter + 1;
end
end
charnum = counter;
else
charnum = -1;
end

Shubham Pandey
Shubham Pandey on 11 Apr 2020
function charnum = char_counter(fname,character)
fid=fopen(fname,'rt');
if fid< 0 || ischar(character)==0
charnum = -1;
return;
end
if ischar(character)==1 && fid>0
contents = fgets(fid);
s=0;
while ischar(contents)
z = sprintf('%s',contents);
char_found = strfind(z,character);
s = s + length(char_found);
contents = fgets(fid);
end
charnum = s;
end
end

Preethi Vannal
Preethi Vannal on 12 Apr 2020
I passed 3 assessments out of 4 for this same question.
My code:
function charnum = char_counter(fname,ch)
if isfile(fname)
fid=fopen(fname,'rt')
if (fid>0 && ischar(ch))
ct=0;
oneline=fgets(fid);
while ischar(oneline)
if(strfind(oneline,ch))
ct=ct+count(oneline,ch);
else
charnum=-1;
end
oneline=fgets(fid);
end
charnum=ct;
else
charnum=-1;
end
else
charnum=0;
end
fclose(fid);
end
I am not able to get idea to pass this 4th assessment.
Can anyone please help me?

  3 Comments

Walter Roberson
Walter Roberson on 12 Apr 2020
If isfile() fails then you return charnum=0 but the assignment requires charnum -1 for that case.
if(strfind(oneline,ch))
ct=ct+count(oneline,ch);
else
charnum=-1;
end
What is the reason you are setting charnum if you do not happen to find the desired character on one particular line?
Preethi Vannal
Preethi Vannal on 13 Apr 2020
Thankyou for clearing this. After this, I wrote the code like this and I passed all the assessments.
function charnum = char_counter(fname,ch)
fid=fopen(fname,'rt')
if (fid<0 || ischar(ch)==0)
charnum=-1;
return;
end
if (fid>0 && (ischar(ch)==1))
ct=0;
oneline=fgets(fid);
while ischar(oneline)
ct=ct+count(oneline,ch);
oneline=fgets(fid);
end
charnum=ct;
end
fclose(fid);
end

Sign in to comment.


Arafat Roney
Arafat Roney on 6 May 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt'); %%FILE IDENTIFIER
if fid>0
oneline=fgets(fid); %%READS ONELINE FROM 'fid'
n=0; %%INITIALIZED TO ZERO AS COUNTER OF THE GIVEN CHARACTER
while ischar(oneline) %%READS ONELINE FROM THE TEXT FILE AND COUNTS THE CHARACTER
c=oneline;
s=length(strfind(c,character));
n=n+s;
oneline=fgets(fid);
end
charnum=n; %% OUTPUT ARGUMENT OF THE FUNCTION
else
charnum=-1; %% OUTPUT ARGUMENT OF THE FUNCTION WHEN INVALID INPUT
end
end

  4 Comments

Show 1 older comment

Sign in to comment.


Arafat Roney
Arafat Roney on 6 May 2020
Edited: Arafat Roney on 8 May 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'r'); %%FILE IDENTIFIER
if fid>0 && ischar(character)
oneline=fgets(fid); %%READS ONELINE FROM 'fid'
n=0; %%INITIALIZED TO ZERO AS COUNTER OF THE GIVEN CHARACTER
while ischar(oneline) %%READS ONELINE FROM THE TEXT FILE AND COUNTS THE CHARACTER
c=oneline;
s=length(strfind(c,character));
n=n+s;
oneline=fgets(fid);
end
charnum=n; %% OUTPUT ARGUMENT OF THE FUNCTION
else
charnum=-1; %% OUTPUT ARGUMENT OF THE FUNCTION WHEN INVALID INPUT
end
fclose(fid);
end

  10 Comments

Show 7 older comments
Arafat Roney
Arafat Roney on 8 May 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'r'); %%FILE IDENTIFIER
if fid>0 && ischar(character)
oneline=fgets(fid); %%READS ONELINE FROM 'fid'
n=0; %%INITIALIZED TO ZERO AS COUNTER OF THE GIVEN CHARACTER
while ischar(oneline) %%READS ONELINE FROM THE TEXT FILE AND COUNTS THE CHARACTER
c=oneline;
s=length(strfind(c,character));
n=n+s;
oneline=fgets(fid);
end
charnum=n; %% OUTPUT ARGUMENT OF THE FUNCTION
fclose(fid);
else
charnum=-1; %% OUTPUT ARGUMENT OF THE FUNCTION WHEN INVALID INPUT
fclose(fid);
end
end

Sign in to comment.


Gyanu Gautam
Gyanu Gautam on 17 May 2020
% Hope this works well for everyone... :)
function charnum = char_counter(fname,chr)
charnum = 0;
fid = fopen(fname,'rt');
if fid < 0 || ~ischar(chr)
charnum = -1;
return
end
oneline = fgets(fid);
while ischar(oneline)
res = strfind(oneline,chr);
charnum = charnum+length(res);
oneline = fgets(fid);
end
fclose(fid);
end

Prithvi Shams
Prithvi Shams on 22 May 2020
Edited: Prithvi Shams on 22 May 2020
function charnum = char_counter(fname, character)
fid = fopen(fname,'rt');
if (fid<0) || (~ischar(character))
charnum = -1;
return %%if invalid input or missing file, control is returned to the user
end
i = 0;
numchar = zeros([1,10000]); %%preallocating based on a hunch;not a good practice, but did it anyway to inspect the execution time
line = fgetl(fid); %%reads line excluding newline
while ischar(line)
i = i + 1;
numchar(i) = count(line,character); %%assigns the input character count for each line to a row vector
line = fgetl(fid);
end
charnum = sum(numchar,'all'); %%adds up the elements of the aforementioned row vector
fclose(fid); %%closes the file when the function runs successfully. The test can be passed without fclose()..
%%but it's good practice to close an open file
end

  1 Comment

Walter Roberson
Walter Roberson on 10 Jun 2020 at 19:27
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.

Sign in to comment.


Shivaani S
Shivaani S on 25 May 2020
i am new to matlab so i am still not acquinted with matlab functions that would make this code simpler.I created a columun vector -x: that contains all the characters using fscanf() . so i used simple for loop for reading a column vector that contains all the characters. then i used if condition to compare the charcters in col vector and increment number. Beginners might find this usful.
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt')
charnum=0;
if fid<0 || ~ischar(character)
charnum=-1;
return
end
x=fscanf(fid,'%c');
for i =1:length(x)
if x(i)==character
charnum=charnum+1;
end
end

  1 Comment

Sign in to comment.


Sohail Khan
Sohail Khan on 27 May 2020
Edited: Sohail Khan on 27 May 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 || ischar(character) == 0
charnum = -1;
error('the file should have excatly three a-s')
return
end
x=fileread(fname)
n=length(x);
count = 0;
for i=1:n
if(x(i)==character) && ischar(character)
count=count+1;
end
end
charnum = count

  1 Comment

Walter Roberson
Walter Roberson on 27 May 2020
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return. You also error() when you were not asked to do so, and the error message is irrelevant and typically incorrect.

Sign in to comment.


Taif Ahmed BIpul
Taif Ahmed BIpul on 31 May 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 || double(character)<32 || double(character)>126
charnum=-1;
return
end
oneline = fgets(fid);
charnum=0;
while ischar(oneline)
A=strfind(oneline,character);
charnum=charnum+length(A);
oneline = fgets(fid);
end
fclose(fid);

  1 Comment

Walter Roberson
Walter Roberson on 10 Jun 2020 at 19:26
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.

Sign in to comment.


Logaheswari Muniraj
Logaheswari Muniraj on 1 Jun 2020
Edited: Logaheswari Muniraj on 1 Jun 2020
Give this a go :) :
function[charnum]=char_counter(fname,character)
fid = fopen(fname,'rt');
m = [];
i = 0;
if fid < 0 || ischar(character)==0
charnum = -1;
return;
else
oneline = fgets(fid);
while ischar(oneline)
A = ismember(oneline,character);
[~,n] = size(find(A));
i = i+1;
m(i) = n;
oneline = fgets(fid);
end
charnum = sum(m);
end
end
fclose(fid);

  2 Comments

Walter Roberson
Walter Roberson on 1 Jun 2020
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.
Walter Roberson
Walter Roberson on 1 Jun 2020
i = i+1;
m(i) = n;
You are counting for every line, growing m as you go. It can get expensive to grow arrays each time: to grow to size N, MATLAB has to move aroud N*(N+1)/2 pieces of information. Now let there be (say) a million lines, and you can see that could add up a lot. And it is unnecessary, since nothing in the question asks how many there are in each line: the only thing that is needed is the total count. You can keep a simple running total.

Sign in to comment.


Sumit Kumar Sharma
Sumit Kumar Sharma on 5 Jun 2020
Edited: Sumit Kumar Sharma on 6 Jun 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 || ~ischar(character)
charnum=-1;
fclose(fid);
return;
else
p=fgets(fid);
charnum=0;
while ischar(p)
charnum=charnum+count(p,character);
p=fgets(fid);
end
end
fclose(fid);
end

  1 Comment

Walter Roberson
Walter Roberson on 5 Jun 2020
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.

Sign in to comment.


Bhavya Khanna
Bhavya Khanna on 9 Jun 2020
function charnum = char_counter(fname,character)
fid = fopen(fname,'r+t');
charnum = 0;
if fid<0 || ~ischar(character)
charnum = -1;
return
end
oneline = fgets(fid);
while ischar(oneline)
for i = 1:length(oneline)
if oneline(i) == character
charnum = charnum + 1;
end
end
oneline = fgets(fid);
end
fclose(fid);
end

  1 Comment

Walter Roberson
Walter Roberson on 10 Jun 2020 at 19:25
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.

Sign in to comment.


ahmed mamdouh
ahmed mamdouh on 10 Jun 2020 at 19:22
Edited: ahmed mamdouh on 10 Jun 2020 at 21:14
function charsum = char_counter(fname,character)
file=fopen(fname,'rt');
count=0;
x=[];
if file<0 || ~ischar(character) || isempty(character)
charsum=-1;
fclose(file);
return;
end
line=fgets(file);
while ischar(line)
count=count+1;
n=strfind(line,character);
x(1,count)=length(n);
line=fgets(file);
end
charsum=sum(x);
fprintf('\n');
fclose(file);
end

  2 Comments

Walter Roberson
Walter Roberson on 10 Jun 2020 at 19:25
When the file is valid but the character parameter is not the proper data type, you leave the file open when you return.
Walter Roberson
Walter Roberson on 10 Jun 2020 at 21:55
You modified the code to fclose() when the datatype is wrong, but if the file fails to open then fid < 0 will be true and you would try to fclose(-1) which would be an error.

Sign in to comment.


Translated by