text file I/O

44 vues (au cours des 30 derniers jours)
asad jaffar
asad jaffar le 20 Avr 2019
Modifié(e) : Jan le 19 Jan 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 commentaires
Ramesh Patel
Ramesh Patel le 15 Juil 2021
Modifié(e) : Ramesh Patel le 15 Juil 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 le 15 Juil 2021
Your code does fopen() but no fclose(), and so does have an error.

Connectez-vous pour commenter.

Réponses (17)

Jiaqi Liu
Jiaqi Liu le 3 Sep 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 commentaires
Aniket Bordekar
Aniket Bordekar le 15 Sep 2020
Why is %c used?
Walter Roberson
Walter Roberson le 15 Sep 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...

Connectez-vous pour commenter.


Muhammad Sadiq
Muhammad Sadiq le 7 Mai 2020
Modifié(e) : Muhammad Sadiq le 7 Mai 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 commentaires
THIERNO AMADOU MOUCTAR BALDE
perfect Thank sir
Walter Roberson
Walter Roberson le 30 Déc 2020
This code fails to fclose(fid) under any circumstances.

Connectez-vous pour commenter.


Fazlul Haque
Fazlul Haque le 15 Mai 2020
done with fgets and while loops
  1 commentaire
Walter Roberson
Walter Roberson le 15 Mai 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.

Connectez-vous pour commenter.


Akshay Dengwani
Akshay Dengwani le 24 Déc 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 commentaires
SOUMYAJIT MONDAL
SOUMYAJIT MONDAL le 2 Sep 2021
Please explain
In the line sum(line==charac) , what does line==charac means ?
Walter Roberson
Walter Roberson le 2 Sep 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 .

Connectez-vous pour commenter.


Pranav Mishra
Pranav Mishra le 8 Juin 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 commentaire
Walter Roberson
Walter Roberson le 8 Juin 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.

Connectez-vous pour commenter.


Hari Kiran Tirumaladasu
Hari Kiran Tirumaladasu le 21 Juin 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 le 23 Juil 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 commentaire
Walter Roberson
Walter Roberson le 23 Juil 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.

Connectez-vous pour commenter.


Walter Roberson
Walter Roberson le 20 Avr 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 commentaires
asad jaffar
asad jaffar le 20 Avr 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 le 20 Avr 2019
Line 33.

Connectez-vous pour commenter.


Arup Kumar Debnath
Arup Kumar Debnath le 1 Juin 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 commentaire
Walter Roberson
Walter Roberson le 1 Juin 2020
Modifié(e) : Walter Roberson le 1 Juin 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.

Connectez-vous pour commenter.


SHASHANK SINGH
SHASHANK SINGH le 7 Juin 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 commentaires
Jobin Geevarghese Thampi
Jobin Geevarghese Thampi le 18 Fév 2021
@Walter Roberson what happens when we doesnt write 'return'. i havent understood about return function could you explain me?
Walter Roberson
Walter Roberson le 20 Fév 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.

Connectez-vous pour commenter.


Ujjawal Barnwal
Ujjawal Barnwal le 8 Juin 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 commentaire
Walter Roberson
Walter Roberson le 12 Juin 2020
If the fname is valid but character is not a character, then you leave the file open when you return.

Connectez-vous pour commenter.


Sachin Patare
Sachin Patare le 27 Sep 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 commentaires
Jan
Jan le 27 Sep 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 le 28 Sep 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.

Connectez-vous pour commenter.


Sumanth Bayya
Sumanth Bayya le 19 Oct 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 commentaires
Walter Roberson
Walter Roberson le 19 Oct 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 le 20 Oct 2021
Modifié(e) : Jan le 20 Oct 2021
% I got it. Thanks, Walter

Connectez-vous pour commenter.


Milad Mehrnia
Milad Mehrnia le 1 Nov 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 commentaire
Walter Roberson
Walter Roberson le 1 Nov 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.

Connectez-vous pour commenter.


Duong Nguyen
Duong Nguyen le 13 Mar 2022
Modifié(e) : Duong Nguyen le 13 Mar 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 commentaire
Walter Roberson
Walter Roberson le 13 Mar 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.

Connectez-vous pour commenter.


Zia Ur Rehman
Zia Ur Rehman le 1 Sep 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 commentaires
Jan
Jan le 3 Sep 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 le 4 Sep 2022
ok ok, i will try this, thanks a lot

Connectez-vous pour commenter.


Rahim Ullah
Rahim Ullah le 18 Jan 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 commentaires
Rahim Ullah
Rahim Ullah le 19 Jan 2023
So should I delete my answer now ???
Jan
Jan le 19 Jan 2023
Modifié(e) : Jan le 19 Jan 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.

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by