text file I/O

132 ビュー (過去 30 日間)
asad jaffar
asad jaffar 2019 年 4 月 20 日
編集済み: Jan 2023 年 1 月 19 日
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 件のコメント
Ramesh Patel
Ramesh Patel 2021 年 7 月 15 日
編集済み: Ramesh Patel 2021 年 7 月 15 日
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 2021 年 7 月 15 日
Your code does fopen() but no fclose(), and so does have an error.

サインインしてコメントする。

回答 (17 件)

Jiaqi Liu
Jiaqi Liu 2019 年 9 月 3 日
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 件のコメント
Aniket Bordekar
Aniket Bordekar 2020 年 9 月 15 日
Why is %c used?
Walter Roberson
Walter Roberson 2020 年 9 月 15 日
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
Muhammad Sadiq 2020 年 5 月 7 日
編集済み: Muhammad Sadiq 2020 年 5 月 7 日
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 件のコメント
THIERNO AMADOU MOUCTAR BALDE
THIERNO AMADOU MOUCTAR BALDE 2020 年 12 月 30 日
perfect Thank sir
Walter Roberson
Walter Roberson 2020 年 12 月 30 日
This code fails to fclose(fid) under any circumstances.

サインインしてコメントする。


Fazlul Haque
Fazlul Haque 2020 年 5 月 15 日
done with fgets and while loops
  1 件のコメント
Walter Roberson
Walter Roberson 2020 年 5 月 15 日
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
Akshay Dengwani 2020 年 12 月 24 日
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 件のコメント
SOUMYAJIT MONDAL
SOUMYAJIT MONDAL 2021 年 9 月 2 日
Please explain
In the line sum(line==charac) , what does line==charac means ?
Walter Roberson
Walter Roberson 2021 年 9 月 2 日
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
Pranav Mishra 2020 年 6 月 8 日
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 件のコメント
Walter Roberson
Walter Roberson 2020 年 6 月 8 日
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
Hari Kiran Tirumaladasu 2020 年 6 月 21 日
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 2020 年 7 月 23 日
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 件のコメント
Walter Roberson
Walter Roberson 2020 年 7 月 23 日
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
Walter Roberson 2019 年 4 月 20 日
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 件のコメント
asad jaffar
asad jaffar 2019 年 4 月 20 日
@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 2019 年 4 月 20 日
Line 33.

サインインしてコメントする。


Arup Kumar Debnath
Arup Kumar Debnath 2020 年 6 月 1 日
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 件のコメント
Walter Roberson
Walter Roberson 2020 年 6 月 1 日
編集済み: Walter Roberson 2020 年 6 月 1 日
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
SHASHANK SINGH 2020 年 6 月 7 日
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 件のコメント
Jobin Geevarghese Thampi
Jobin Geevarghese Thampi 2021 年 2 月 18 日
@Walter Roberson what happens when we doesnt write 'return'. i havent understood about return function could you explain me?
Walter Roberson
Walter Roberson 2021 年 2 月 20 日
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
Ujjawal Barnwal 2020 年 6 月 8 日
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 件のコメント
Walter Roberson
Walter Roberson 2020 年 6 月 12 日
If the fname is valid but character is not a character, then you leave the file open when you return.

サインインしてコメントする。


Sachin Patare
Sachin Patare 2020 年 9 月 27 日
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 件のコメント
Jan
Jan 2020 年 9 月 27 日
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 2020 年 9 月 28 日
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
Sumanth Bayya 2021 年 10 月 19 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 10 月 19 日
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 2021 年 10 月 20 日
編集済み: Jan 2021 年 10 月 20 日
% I got it. Thanks, Walter

サインインしてコメントする。


Milad Mehrnia
Milad Mehrnia 2021 年 11 月 1 日
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 件のコメント
Walter Roberson
Walter Roberson 2021 年 11 月 1 日
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
Duong Nguyen 2022 年 3 月 13 日
編集済み: Duong Nguyen 2022 年 3 月 13 日
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 件のコメント
Walter Roberson
Walter Roberson 2022 年 3 月 13 日
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
Zia Ur Rehman 2022 年 9 月 1 日
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 件のコメント
Jan
Jan 2022 年 9 月 3 日
@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 2022 年 9 月 4 日
ok ok, i will try this, thanks a lot

サインインしてコメントする。


Rahim Ullah
Rahim Ullah 2023 年 1 月 18 日
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 件のコメント
Rahim Ullah
Rahim Ullah 2023 年 1 月 19 日
So should I delete my answer now ???
Jan
Jan 2023 年 1 月 19 日
編集済み: Jan 2023 年 1 月 19 日
@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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeLarge Files and Big Data についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by