text file I/O

90 visualizaciones (últimos 30 días)
asad jaffar
asad jaffar el 20 de Abr. de 2019
Editada: Jan el 19 de En. de 2023
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
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
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
Walter Roberson el 15 de Jul. de 2021
Your code does fopen() but no fclose(), and so does have an error.

Iniciar sesión para comentar.

Respuestas (17)

Jiaqi Liu
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
Aniket Bordekar
Aniket Bordekar el 15 de Sept. de 2020
Why is %c used?
Walter Roberson
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...

Iniciar sesión para comentar.


Muhammad Sadiq
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
THIERNO AMADOU MOUCTAR BALDE
THIERNO AMADOU MOUCTAR BALDE el 30 de Dic. de 2020
perfect Thank sir
Walter Roberson
Walter Roberson el 30 de Dic. de 2020
This code fails to fclose(fid) under any circumstances.

Iniciar sesión para comentar.


Fazlul Haque
Fazlul Haque el 15 de Mayo de 2020
done with fgets and while loops
  1 comentario
Walter Roberson
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.

Iniciar sesión para comentar.


Akshay Dengwani
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
SOUMYAJIT MONDAL el 2 de Sept. de 2021
Please explain
In the line sum(line==charac) , what does line==charac means ?
Walter Roberson
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 .

Iniciar sesión para comentar.


Pranav Mishra
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
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.

Iniciar sesión para comentar.


Hari Kiran Tirumaladasu
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);

Adityesh Satam
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
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.

Iniciar sesión para comentar.


Walter Roberson
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
asad jaffar
asad jaffar el 20 de Abr. de 2019
@walter roberson can you tell me the line number where i have to return 0 and not -1 , i mean to say at which line do i have to make changes?
Walter Roberson
Walter Roberson el 20 de Abr. de 2019
Line 33.

Iniciar sesión para comentar.


Arup Kumar Debnath
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
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.

Iniciar sesión para comentar.


SHASHANK SINGH
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
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
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.

Iniciar sesión para comentar.


Ujjawal Barnwal
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
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.

Iniciar sesión para comentar.


Sachin Patare
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
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
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.

Iniciar sesión para comentar.


Sumanth Bayya
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
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.
Jan
Jan el 20 de Oct. de 2021
Editada: Jan el 20 de Oct. de 2021
% I got it. Thanks, Walter

Iniciar sesión para comentar.


Milad Mehrnia
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
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.

Iniciar sesión para comentar.


Duong Nguyen
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
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.

Iniciar sesión para comentar.


Zia Ur Rehman
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
Jan el 3 de Sept. de 2022
@Zia Ur Rehman: If you use fileread, there is no need to open the file with fopen before.
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.
Zia Ur Rehman
Zia Ur Rehman el 4 de Sept. de 2022
ok ok, i will try this, thanks a lot

Iniciar sesión para comentar.


Rahim Ullah
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
Rahim Ullah
Rahim Ullah el 19 de En. de 2023
So should I delete my answer now ???
Jan
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.

Iniciar sesión para comentar.

Categorías

Más información sobre Large Files and Big Data 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!

Translated by