text file I/O
44 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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
solution: this is copied from this link https://www.mathworks.com/matlabcentral/answers/453328-assignment-text-files-write-a-function-called-char_counter-that-counts-the-number-of-a-certain-char
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
can you guys tell whats wrong with this code?
4 comentarios
Ramesh Patel
el 15 de Jul. de 2021
Editada: Ramesh Patel
el 15 de Jul. de 2021
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
if fid<0|| ~ischar(character)
charnum=-1;
else
charnum=0;
oneline = fgets(fid);
while ischar(oneline)
n = strfind(oneline,character);
charnum = charnum + length(n);
oneline = fgets(fid);
end
end
end
%this is simplest code and having no error
Walter Roberson
el 15 de Jul. de 2021
Your code does fopen() but no fclose(), and so does have an error.
Respuestas (17)
Jiaqi Liu
el 3 de Sept. de 2019
function charnum = char_counter(frame,character)
fid = fopen(frame,'r');
if fid < 0
charnum = -1;
return
end
if ischar(character) == 0
charnum = -1;
return
end
inhalt = fscanf (fid, '%c');
charnum = count(inhalt,character);
end
2 comentarios
Walter Roberson
el 15 de Sept. de 2020
fscanf() without a count asks MATLAB to read as far as possible in the file that still matches the given format. The format given is %c, which matches any one character, and since every byte stored in the file can be interpreted as a character, the result of using fscanf with '%c' format and no count, is to read the entire rest of the file one character at a time.
... Some day I should test with R2020a or later, and a byte stream that does not represent valid UTF8, to see whether %c would stop reading at that point...
Muhammad Sadiq
el 7 de Mayo de 2020
Editada: Muhammad Sadiq
el 7 de Mayo de 2020
function charnum = char_counter(frame,character)
fid = fopen(frame,'r');
if fid < 0
charnum = -1;
return
end
if ischar(character) == 0
charnum = -1;
return
end
inhalt = fscanf (fid, '%c');
charnum = count(inhalt,character);
end
3 comentarios
Fazlul Haque
el 15 de Mayo de 2020
done with fgets and while loops
1 comentario
Walter Roberson
el 15 de Mayo de 2020
If the file is valid but charv is not a character, then you leave the file open when you return.
We recommend against using sum as the name of a variable: it is very common to get confused and also want to use sum() as the name of the summation function in the same code where you use sum as a variable.
Akshay Dengwani
el 24 de Dic. de 2020
function charnum = char_counter(fname,charac)
fid = fopen(fname, 'rt');
if fid < 0
charnum = -1;
return
end
line = fgets(fid);
su = 0;
while ischar(line)
lo = line == charac;
su = su + sum(lo(:));
line = fgets(fid);
end
if double(charac)>127 || double(charac)<0 || ~ischar(charac);
charnum = -1;
else
charnum = su;
end
end
4 comentarios
SOUMYAJIT MONDAL
el 2 de Sept. de 2021
Please explain
In the line sum(line==charac) , what does line==charac means ?
Walter Roberson
el 2 de Sept. de 2021
fread() with '*char' and inf size will cause fread() to return a character vector that contains all remaining characters in the file. Those will be stored in the variable named line
Character vectors are (for most purposes) stored as arrays of 16 bit integers that are unicode code points. Unicode is an international standard that gives a specific ordering to lots and lots of characters and symbols; https://home.unicode.org/ . For example the character 'A' is stored as 16 bit integer with value 65. They really are numeric internally (together with a flag that says that the numeric values represent characters.)
The == operator is the equality test operator. In this context, == is used to compare the character codes (integer) used to represent the data in the line variable, to the character code that is used to represent the character that is stored in charac which is known to be a single character. So internally you have a numeric vector ('line') being compared to a numeric scalar ('charac') . The result of comparing a vector and a scalar is defined by MATLAB to be a logical vector, in which the value is false for each place the comparison failed, an true for each place the comparison succeeded. So the output of == is a logical vector the same length as the variable line .
What you need to know after that point is that logical false is represented by numeric value 0, and logical true is represented by the numeric value 1. Because of that, when you want to know how many locations the comparison held at, you can sum() the vector, which contributes 1 to the sum for every true and the result at the end is going to be the number of places the comparison was true.
So what will be stored in su is the number of places a character in the variable line was the same as the character in the variable charac .
Pranav Mishra
el 8 de Jun. de 2020
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
if (fid < 0)
charnum = -1;
return;
end
if (ischar(character) ==0)
charnum = -1;
else
c = 0;
oneline = fgets(fid);
while ischar(oneline)
character_line = char(oneline);
[a b] = size(strfind(character_line,character));
c = c + b;
oneline = fgets(fid);
end
charnum = c;
end
fclose(fid);
end
1 comentario
Walter Roberson
el 8 de Jun. de 2020
Note that the result of fgets() is already a character vector (unless end of file), so you do not need to use char() on oneline.
Hari Kiran Tirumaladasu
el 21 de Jun. de 2020
function charnum = char_counter(fname,character)
fid = fopen(fname,'r');
if fid < 0 || ischar(character) == 0
charnum = -1;
error('The file entered is either incorrect or the character entered could not be found');
return;
end
incount = fscanf(fid,'%c');
charnum = count(incount,character);
0 comentarios
Adityesh Satam
el 23 de Jul. de 2020
I was able to get all correct using this code:
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
charnum = 0;
ii = 0;
if fid < 0
charnum = -1;
return;
end
if ischar(character) == 0
charnum = -1;
end
% Reading a file one line at a time
one_line = fgets(fid);
while ischar(one_line)
for ii = 1:length(one_line)
if strcmp(one_line(ii),character) && ischar(character)
charnum = charnum + 1;
end
end
one_line = fgets(fid);
end
fclose(fid);
end
1 comentario
Walter Roberson
el 23 de Jul. de 2020
If the character parameter is not a valid parameter, you go ahead and read the file anyhow, but each time testing again that ischar(character) is true. That is a waste of time. If ischar(character) is false then do not bother reading the file.
Walter Roberson
el 20 de Abr. de 2019
We already explained. If you are passed something that is a character but the character is not found in the file then you need to return 0 not -1. Only return -1 if the file does not exist or what you are passed is not character data type.
2 comentarios
Arup Kumar Debnath
el 1 de Jun. de 2020
I was trying to answer this question. But i stuck there, Can any one help me and find the fault in this code?
Disclaimer= I am a noob here.
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0
error('error opening file\n');
charnum=-1;
return;
end
total=fgets(fid);
ii=1;
a=size(total);
charnum=0;
while ii<=a
if total(ii)=='character';
charnum=charnum+1;
else
ii=ii+1;
end
end
1 comentario
Walter Roberson
el 1 de Jun. de 2020
Editada: Walter Roberson
el 1 de Jun. de 2020
you do not validate that the second input is a character.
You are comparing the input to the literal character vector ['c' 'h' 'a' 'r' 'a' 'c' 't' 'e' 'r'] instead of to what the input variable named character holds.
You are not incrementing ii if the comparison is true.
SHASHANK SINGH
el 7 de Jun. de 2020
function charnum = char_counter(fname, character)
fid = fopen(fname,'r');
if fid < 0 || ischar(character) == 0
charnum = -1;
return
end
inhalt = fscanf(fid, '%c');
charnum = count(inhalt, character);
end
3 comentarios
Jobin Geevarghese Thampi
el 18 de Feb. de 2021
@Walter Roberson what happens when we doesnt write 'return'. i havent understood about return function could you explain me?
Walter Roberson
el 20 de Feb. de 2021
When return is encountered, MATLAB leaves the function and goes back to the place it was called, exactly the same as if MATLAB had reached the end of the function. It does not execute any more code in the function.
In the code that Shashank Singh posted, if the return had not been there, then after charnum was assigned -1, the code would continue on after the if , and so the code would attempt to do the fscanf(). But if the fid was < 0 indicating the file could not be opened, then fscanf(fid) would be an error and the function would crash.
It is always possible to rewrite code that uses return to not use return, but it can be messy to do so. In the case of the above code it could be instead written as
function charnum = char_counter(fname, character)
fid = fopen(fname,'r');
if fid < 0 || ischar(character) == 0
charnum = -1;
else
inhalt = fscanf(fid, '%c');
charnum = count(inhalt, character);
end
end
which is not bad at all in this case. But consider proper checking of ischar():
function charnum = char_counter(fname, character)
if ischar(character) == 0
charnum = -1;
else
fid = fopen(fname,'r');
if fid < 0
charnum = -1;
else
inhalt = fscanf(fid, '%c');
charnum = count(inhalt, character);
end
end
end
and compare that to the same with return:
function charnum = char_counter(fname, character)
if ischar(character) == 0
charnum = -1;
return
end
fid = fopen(fname,'r');
if fid < 0
charnum = -1;
return
end
inhalt = fscanf(fid, '%c');
charnum = count(inhalt, character);
end
Notice that using return the code is more compact and does not need as many if/else levels.
Ujjawal Barnwal
el 8 de Jun. de 2020
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt');
charnum = 0;
if fid < 0 || ~ischar(character)
charnum = -1;
return;
end
oneline = fgets(fid);
while ischar(oneline)
a=length(findstr(oneline,character));
charnum = charnum + a;
oneline = fgets(fid);
end
fclose(fid);
end
1 comentario
Walter Roberson
el 12 de Jun. de 2020
If the fname is valid but character is not a character, then you leave the file open when you return.
Sachin Patare
el 27 de Sept. de 2020
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
if fid<0
charnum=-1;
return
end
x=fileread(fname);
if ischar(character)==1
a=findstr(x,character);
b=size(a);
charnum=b(1,2);
else
charnum=-1;
end
3 comentarios
Jan
el 27 de Sept. de 2020
If you use fileread, you can omit the fopen. If you use fopen, do not forget to close the file with fclose.
numel() is easier than getting the 2nd output from size. ischar replies a logical already, so there is no need to compare it with "== 1".
findstr is deprecated for more than 10 years now. Use strfind instead.
function charnum=char_counter(fname, character)
charnum = -1; % Default value
if exist(fname, 'file') == 2 % Check existence of file
s = fileread(fname);
if ischar(character) && isscalar(character)
charnum = sum(s == character);
% Or charnum = numel(strfind(s, character));
end
end
Walter Roberson
el 28 de Sept. de 2020
The one advantage of testing the fopen() over testing file existence with exist, is that fopen() will fail smoothly if the file exists but you do not have permission to read it, or the file exists but it is locked so you cannot read it at the moment. In either of those cases, fileread() would generate an exception that would have to be handled with a try/catch to replicate the fopen() ability to detect that the file cannot be read.
Sumanth Bayya
el 19 de Oct. de 2021
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt');
charnum=0;
ii=0;
if fid<0
charnum=-1;
return
end
if ischar(character)==0
charnum=-1;
end
one_line=fgets(fid);
while ischar(one_line)
for ii=1:length(one_line)
if strcmp(one_line(ii),character)&& ischar(character)
charnum=charnum+1;
end
end
one_line=fgets(fid);
end
fclose(fid);
end
4 comentarios
Walter Roberson
el 19 de Oct. de 2021
If you look at the right hand side of the "Insert" controls, the blob to the right of the paperclip is the "Code examples" button. It allows you to insert formatted code that is not executed if you "Run".
This is one of the facilities carried over from LiveScript. In the context of LiveScript it makes more sense that there would be cases where you need a block of code to be formatted but not executable.
Milad Mehrnia
el 1 de Nov. de 2021
function charnum = char_counter(fname,c)
fid = fopen(fname,'rt');
charnum = 0;
if ~ischar(c)
charnum = -1;
elseif fid < 0
charnum = -1;
else
line = fgets(fid);
while ischar(line)
for i = 1:length(line)
if line(1,i) == c
charnum = charnum + 1;
end
end
line = fgets(fid);
end
fclose(fid);
end
end
1 comentario
Walter Roberson
el 1 de Nov. de 2021
In the case where the file exists and is readable, but the user entered something that was not a character for the second parameter, then you open the file but you do not close it.
Duong Nguyen
el 13 de Mzo. de 2022
Editada: Duong Nguyen
el 13 de Mzo. de 2022
function charnum = char_counter(fname,character)
fid = fopen(fname, 'rt');
charnum = 0;
if fid<0||~(ischar(character))
charnum = -1;
return
end
%if you not use 'return' the while loop below will assign charnum = 0;
oneline = fgets(fid);
while ischar(oneline)
[~,temp] = size(strfind(oneline,character));
charnum = charnum + temp;
oneline = fgets(fid);
end
fclose(fid);
1 comentario
Walter Roberson
el 13 de Mzo. de 2022
In the case where the file exists and is readable, but the user entered something that was not a character for the second parameter, then you open the file but you do not close it.
Zia Ur Rehman
el 1 de Sept. de 2022
Hi folks,
please check my code and suggest me if I can improve this
function charnum = char_counter(fname,character)
fid = fopen(fname,'rt'); % opening the text named(fname) file to read(rt)
if fid<0 || ~ischar(character) % checking the existance of file and checking if second argument of char_counter is valid char
%fprintf('Error opening file %s\n\n',fname);
charnum = -1;
return;
end
charnum=0;
oneline = fgets(fid); % reading 1st line using 'fgets'
while ischar(oneline)
for i = 1:length(oneline) % loop for traversing through each char of the line
b = strcmp(oneline(i),character); % comparing ith char with 2nd argument(character)
if b
charnum= charnum+1; % if we find the char then add 1
end
end
oneline = fgets(fid); %reading the next line and returned to online
end
fclose(fid); % closing the file
end
6 comentarios
Jan
el 3 de Sept. de 2022
You can simplify:
b = strcmp(file_text(i),character); % comparing ith char with 2nd argument(character)
if b
charnum= charnum+1; % if we find the char then add 1
end
to
charnum = charnum + strcmp(file_text(i),character);
strcmp replies true or false, which is converted to 1 or 0.
But you can avoid the loop: file_text == character replies a vector of 0 and 1 also. Then sum() counts the matchs.
See also: isfile, fileread. Then 6 lines of code solve the problem.
Rahim Ullah
el 18 de En. de 2023
your code looks lengthy and complex please try this one
function charnum=char_counter(fname,character)
fid=fopen(fname,'rt'); %file open
if fid<0 %check if the file open correctly or not
fprintf('file cant be open')
charnum=-1; %in case file is not opened due to any reason
return
end
file_content=fileread(fname); % reads the file contents and store it as a string
charnum=sum(file_content==character); %sum all the matching characters found in the strings
if ischar(character)==0 %check for valid character
charnum=-1;
return
end
5 comentarios
Jan
el 19 de En. de 2023
Editada: Jan
el 19 de En. de 2023
@Rahim Ullah: Your answer is a valid contribution concerning Matlab and does not violate the policies. Therefore the editors will not remove it.
I'd insert an fclose(fid) or use isfile() instead. But this is your contribution. Feel free to do, what you like.
Ver también
Categorías
Más información sobre Create Fixed-Point Objects in MATLAB en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!