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. The function returns charnum, the number of characters found. If the file is not found or character is not a valid char, the function return -1. As an example, consider the following run. The file "simple.txt" contains a single line: "This file should have exactly three a-s..." charnum = char_counter('simple.txt','a') charnum = 3

4 commentaires

Walter Roberson
Walter Roberson le 24 Mar 2019
Because you specify that it is a text file, the required output is poorly defined for the cases where the character to search for is either carriage return or newline.
They key is to use the fileread function
function charnum = char_counter(fname,character)
if ischar(character)==0 | fopen(fname)==-1
charnum=-1
else
A=double(char(fileread(fname)))';
charnum=sum(A==double(character));
end
end
Walter Roberson
Walter Roberson le 1 Fév 2020
You leak open files. You open the file but do not close it. MATLAB does not automatically close files when you return from a function.

Connectez-vous pour commenter.

Réponses (6)

Kumar Vivek
Kumar Vivek le 14 Mai 2020

1 vote

function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
if (fid<0) || ~ischar(character)
charnum = -1;
return;
end
oneline = fgets(fid);
charnum = 0;
while (ischar(oneline)) || (strcmp(character,oneline)==1)
f = strfind(oneline,character);
charnum = charnum + length(f);
oneline = fgets(fid);
end
end

5 commentaires

Walter Roberson
Walter Roberson le 15 Mai 2020
If the file name is valid but the second entry is not character type, then the fopen will succeed but the ischar() test will fail, leading you to return, without having fclose() after the successful fopen.
If the ischar(oneline) fails, then you are at end of file, but you continue on with || of strcmp() . Under what circumstances could the strcmp() succeed at end of line, that you would want to use || ?
zineb britel
zineb britel le 6 Juin 2020
i have not understood this linem could you please explain?
while (ischar(oneline)) || (strcmp(character,oneline)==1)
Walter Roberson
Walter Roberson le 6 Juin 2020
that strcmp does not appear to be correct code.
Farhaan Zaidi Bhat
Farhaan Zaidi Bhat le 14 Déc 2020
Can someone tell me what affect did the return statement have?
return causes matlab to leave the function. The values that will be returned to the caller will be according to whatever has been assigned at that point in the execution. In this particular case, the caller would receive the value -1 .
Because the function has been left, the code would not continue on to
oneline = fgets(fid);
You would be in trouble if you did continue on to that point, as the case of fid<0 corresponds to a failure to open the file, and if the file could not be opened there is no way you can read from the file.
Another equivalent way of writing the code would be
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
if (fid<0) || ~ischar(character)
charnum = -1;
else
oneline = fgets(fid);
charnum = 0;
while (ischar(oneline)) || (strcmp(character,oneline)==1)
f = strfind(oneline,character);
charnum = charnum + length(f);
oneline = fgets(fid);
end
end
end
However, situations in which return() tend to get used can be more difficult to convert than this, such as if you are inside a loop.

Connectez-vous pour commenter.

Kodavati Mahendra
Kodavati Mahendra le 24 Mar 2019

0 votes

charnum = char_counter('simple.txt','a')
function charnum = char_counter(a,b);
f = fopen(a);
c = textscan(f,'%s');
charnum = sum(sum(char(c{:})==b));
end
Something lilke this?

13 commentaires

Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
  • Test with all visible charactersVariable charnum has an incorrect value. When testing with ' ' your solution returned 1462056 which is incorrect. (75444)
  • Assessment result: incorrectInvalid inputVariable charnum has an incorrect value. char_counter('simple.txt',11) failed...
  • Assessment result: incorrectNon existent file
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
@Kodavati Mahendra can you please resolve this problem
Kodavati Mahendra
Kodavati Mahendra le 24 Mar 2019
  • Test with all visible charactersVariable charnum has an incorrect value. When testing with ' ' your solution returned 1462056 which is incorrect. (75444)
i do not have the simple.txt file with me. Your question doesnt describe its formatting. So the numbers 1462056 and 75444 do not make any sense with me.
  • Assessment result: incorrectInvalid inputVariable charnum has an incorrect value. char_counter('simple.txt',11) failed...
Your question said that the second argument is a char. 11 is not a character, MATLAB assumes it to be a variable of datatype double.
I am sorry, I cannot be of much help :-)
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
Okay no problem
Walter Roberson
Walter Roberson le 24 Mar 2019
You know how this goes by now, Priyamvada Shankar: you have to propose a solution, and we will help you debug it. Do not expect people to do your homework for you.
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
Modifié(e) : Priyamvada Shankar le 24 Mar 2019
You may find it helpful to download the files for testing and dubugging in MATLAB.
simple.txt
Frankenstein-by-Shelley.txt
function charnum = char_counter(a,b);
f = fopen(a);
c = textscan(f,'%s');
num = sum(sum(char(c{:})==b));
if num==0
charnum= -1
else charnum=num
end
Assessment result: incorrectTest with all visible characters
Variable charnum has an incorrect value.
When testing with ' ' your solution returned 1462056 which is incorrect. (75444)
Assessment result: incorrectNon existent file
Walter Roberson
Walter Roberson le 24 Mar 2019
The program requirements are that if the pass character (second parameter) is not a valid char, then the code has to return -1. You would test for valid characters by checking that it is datatype char and that the number of elements is exactly 1. https://www.mathworks.com/help/matlab/data-type-identification.html
The program requirements also require that you return -1 if the file is not found. If the file is not found then fopen() will return a value that is negative, so you have to test the result of fopen before you use it.
The code you are using to scan the file with textscan is going to skip all whitespace, including spaces and carriage return and newline. I would not recommend using textscan() for this program. fread() would be more appropriate.
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
Modifié(e) : Priyamvada Shankar le 24 Mar 2019
function charnum = char_counter(a,b);
if isa(b,'char')==1
f = fopen(a);
if f~=-1
c = fread(f,'*char')';
charnum = sum(sum(char(c{:})==b));
else charnum=-1
end
else charnum =-1
end
This file should have exactly three a-s...
Brace indexing is not supported for variables of this type.
Error in char_counter (line 6)
charnum = sum(sum(char(c{:})==b));
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
Could you please correct this code?
Walter Roberson
Walter Roberson le 24 Mar 2019
After the fread, c will not be a cell array. You would just use c instead of char(c{:})
Note: you are not testing whether b is exactly one character.
Priyamvada Shankar
Priyamvada Shankar le 24 Mar 2019
Thank you so much
paul mary
paul mary le 24 Mar 2019
@Walter Roberson, Thank you so much, you gave me the best tip.
So Priyamvada, I can give you some hints.
  1. does the file exist? think about function exist() in matlab documentation
  2. think about count() function
  3. Using fread() function is the right thing to do.
asad jaffar
asad jaffar le 20 Avr 2019
@priyamvada shanker ,can you kindly guide me ? i am using the same code of yours but it is giving error ,can someone here give me few hints or tell me about the alogrithm.

Connectez-vous pour commenter.

sadek kouz
sadek kouz le 18 Mar 2020

0 votes

i tried this but i still got an error for
Assessment result: incorrectTest with all visible characters
Variable charnum has an incorrect value. When testing with ' ' your solution returned 2 which is incorrect. (75444)
function charnum = char_counter(filename,character)
charnum=0;
if ~ischar(character)
charnum=-1;
return;
end
if length(character)~=1
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=strfind(a,character);
charnum=length(c);
oneline=fgets(fid);
end
end

3 commentaires

charnum=length(c);
That only counts for that one line. You need to create a total for the entire file.
I am not clear as to why you are bothering to do the sprintf and searching that?
Notice that your sprintf() is adding a newline and a space to every line it processes. That is going to lead to incorrect counts whenever you are asked to count newlines or spaces.
function charnum=char_counter(fname,character)
fid = fopen(fname, 'rt');
if fid<0 || ischar(character)==0
%error('error opening file %s\n\n', fname);
charnum=-1; %for not valid chars or files
return
end
online = fgets(fid); n=0; % this loop is for checking line by line.
while ischar(online)
for ii=1:length(online)
p=online(ii);
if ischar(p)
if (p == character)
n=n+1;
end
end
end
online=fgets(fid);
end
if n==0
charnum=0;
else charnum=n; end
fclose(fid);
If the file name is valid but the second entry is not character type, then the fopen will succeed but the ischar() test will fail, leading you to return, without having fclose() after the successful fopen.
while ischar(online)
In order for that to succeed, online must be character data type. In MATLAB, if an array is a particular data type, every element of the array is also that data type. (In some cases involving handle mixins, the elements of the array might also satisfy more restrictive data types as well.)
p=online(ii);
In order to get here, online must have been character data type. When it is, each element extracted from it must also be character data type.
if ischar(p)
You could not have reached this statement if p was not a char, so there is no point doing this test.

Connectez-vous pour commenter.

Kumar Shubham
Kumar Shubham le 16 Juil 2020
Modifié(e) : Kumar Shubham le 16 Juil 2020

0 votes

after hours i was able to come up with the code that passes test cases.
function charnum = char_counter(filename,character)
%deals with all negations
fid = fopen(filename,'rt');
charnum=0;
if ~ischar(character) || length(character)~=1 || fid<0
charnum=-1;
return;
end
%the concerned code for test case 1 and 2
tline=fgetl(fid);
while ischar(tline)
matches=strfind(tline,character);
num=length(matches);
if num>0
charnum=charnum+num;
end
tline=fgetl(fid);
end
above is more like a combiantion of different ideas from various answers, i suppose there is room for efficiency, please give your input.

3 commentaires

If the file name is valid but the second entry is not character type, then the fopen will succeed but the ischar() test will fail, leading you to return, without having fclose() after the successful fopen.
if num>0
charnum=charnum+num;
end
In the case that num = 0, the cost of doing the if test is a lot more than the cost of adding the zero "needlessly", so it is more efficient to just charnum=charnum+num; without testing.
function charnum = char_counter(filename,character)
fid = fopen(filename,'rt');
charnum=0;
if ~ischar(character) || length(character)~=1 || fid<0
charnum=-1;
return;
end
oneline=fgets(fid);
while ischar(tline)
matches=strfind(tline,character);
num=length(matches);
charnum=charnum+num;
oneline=fgets(fid);
end
fclose(fid);
Walter Roberson
Walter Roberson le 18 Mar 2021
You do not always close the file that you succeed in opening.

Connectez-vous pour commenter.

Sravani Kurma
Sravani Kurma le 28 Juil 2020
Modifié(e) : Sravani Kurma le 28 Juil 2020

0 votes

function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0 % for invalid file,return -1
charnum= -1;
return
end
count=0;
if fid ~=0 && ischar(character)==true
oneline=fgets(fid); %copy file text to oneline
while ischar(oneline) % to check line by line
for i=1:1:length(oneline) % each and every character of oneline is compared with the given input charcter
if oneline(i)==character % if characters matched,count increment
count=count+1;
end
end
oneline=fgets(fid);% update nextline
end
charnum=count; %final count stored in charnum
else
charnum=-1;
end
fclose(fid)

3 commentaires

Walter Roberson
Walter Roberson le 28 Juil 2020
Under what circumstances could fid == 0 in order that fid ~=0 is useful ?
Note: You do not close the file after you open it.
Sravani Kurma
Sravani Kurma le 28 Juil 2020
Modifié(e) : Sravani Kurma le 28 Juil 2020
MATLAB has reserved values of fid like fid==0 for std input ,
fid ==1 for std o/p,
fid ==2 for std error.
As the given file is for binary read access,i can take f>2 or f~=0(since no reserved values are possibily found).
Ya fclose has to be done .... I will edit that
Yes, MATLAB has those reserved file identifiers, but
fid=fopen(fname,'rt');
will never return 0, 1, or 2, so there is no point in testing for the possibility.

Connectez-vous pour commenter.

Ahmed Saleh
Ahmed Saleh le 29 Mar 2021
Modifié(e) : Ahmed Saleh le 29 Mar 2021

0 votes

function charnum = char_counter(fname,character)
if ~ischar(fname) || character <32 || character >126
charnum=-1;
return
end
fid=fopen(fname,'rt');
if fid <0 || nargin<2
charnum=-1;
return
end
text = fgets(fid);
char=[];
while ischar(text)
char=[char,text];
text = fgets(fid);
end
s=size(char);
count=0;
for ii=1:s(2)
logic=strcmp(character,char(1,ii));
if logic==1
count=count+1;
end
end
charnum=count;

1 commentaire

Walter Roberson
Walter Roberson le 30 Mar 2021
If nargin < 2 then character will not be defined for the test in your first if , so it does not make sense to test nargin < 2 after that if test.
Character positions less than 32 are valid characters -- especially 10 (newline) and 13 (carriage return)
However, if the user passes a number in as the second parameter, then that would not be a valid character. And if you thought that the character was being passed in as a number, you failed to check for possibilities such as 98.6

Connectez-vous pour commenter.

Catégories

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by