How to get the length of a formatted string read in using fscanf in SystemVerilog? - system-verilog

I am reading a text file which has string test cases and decode them to process as Verilog test constructs to simulate. The code that I use to read a file is as follows:
integer pntr,file;
string a,b,c,d;
initial
begin
pntr = $fopen(FOO, "r");
end
always
begin
if(!$feof(pntr))
begin
file = $fscanf(pntr, "%s %s %s %s \n", a,b,c,d);
end
else
$fclose(pntr);
I have tried using
integer k;
k = strlen($fscanf(pntr, "%s %s %s %s \n", a,b,c,d));
$display(k);
and the display statement outputs an "x"
I also tried using
$display(file)
but this also gives me x as the display output. The above code is just a representation of my problem, I am using a larger formatted string to read in larger data. Each line of my testcase may have different size. I have initialized the format to the maximum number of string literals that my testcase can have. I wanted to ask if there is a way to get the length of each line that I read or number of string literals that fscanf read ?
Note: I am using Cadence tools for this task.
Input file looks like
read reg_loc1
write regloc2 2.5V regloc3 20mA
read regloc3 regloc5 regloc7

It's hard to debug your code when you have lots of typos and incomplete code. And you also have a race condition in that pntr may not have been assigned from $fopen if the always block executes before the initial block.
But in any case, the problem with using $fscanf and the %s format is that a newline gets treated as whitespace. It's better to use $fgets to read a line at a time, and the use $sscanf to parse the line:
module top;
integer pntr,file;
string a,b,c,d, line;
initial begin
pntr = $fopen("FOO", "r");
while(!$feof(pntr))
if ((file = $fgets(line,pntr)!=0)) begin
$write("%d line: ", file, line);
file = $sscanf(line, "%s %s %s %s \n", a,b,c,d);
$display(file,,a,b,,c,,d);
end
$fclose(pntr);
end
endmodule

Related

Trying to load text file into Octave GUI into the correct format

I have a text file that contains 10 columns separated by comas and X number of rows denoted by return. The initial header line of the data is a string. The first two columns are character strings while the last 8 columns are integers. So far I have tried fscanf:
t1 = fscanf( test, '%c', inf );
which will import the data as large 1 by XXXXX character matrix and textread which imports it but does not format it correctly:
[a,b,c,d,e,f,g,h,i,j] = textread("test.txt", "%s %s %s %s %s %s %s %s %s %s",\
'headerlines', 1);
I suspect its a simple issue of formatting the notation on textread correctly to get my desired output. Any help is greatly appreciated.

mattlab: remove SUB char from end of text file

I import text in matlab using importdata
A = importdata(logFile, '\t', 1);
this works fine, unless the "SUB" char is at the end of the file.
In this case I get the error
Error in
matlab.graphics.internal.figfile.FigFile/read>#(hObject,eventdata)uiProjekt('menuEvalAllData_Callback',hObject,eventdata,guidata(hObject))
Caused by:
Error using vertcat
Dimensions of matrices being
concatenated are not
consistent.
My question is: how can I work around this error?
The simplest idea would be to remove the char from the file before. But how would I remove a single char from a large text file efficiently?
You can use strrep to replace the SUB char. strrep is pretty efficient and should be fast even with large files.
The decimal value of the SUB char in ASCII is 26.
Here's an example code that removes the SUB char from an input file input.txt:
% Open files:
inputID = fopen('input.txt','r');
outputID = fopen('output.txt','w');
file_data=fread(inputID,'*char')'; % Read all data from input file
file_data_fixed = strrep(file_data,char(26),''); % Find and replace the SUB char with blank
fprintf(outputID,'%s',file_data_fixed); % Print all data (without SUB) to output file
% Close files:
fclose(inputID);
fclose(outputID);

Printing a warning message over multiple lines

I am trying to print a warning message that is a little long and includes 2 variable calls. Here's my code:
warning( 'MATLAB:questionable_argument', ...
'the arguments dt (%d) and h (%d) are sub-optimal. Consider increasing nt or decreasing nx.', ...
dt, h )
Obviously, the line of text extends to the right when viewing the MATLAB code. How can I break it so it wraps nicely? I've tried multiple things but keep getting syntax errors.
As suggested in comments, just insert a \n where you want to break the line. You can also use a variable for the text, to make it easy to read also within the code:
txt = sprintf(['the arguments dt (%d) and h (%d) are sub-optimal.\n'...
'Consider increasing nt or decreasing nx.'],dt,h);
warning( 'MATLAB:questionable_argument',txt)
If you just embed escape characters such as \n in a warning string, it will not work:
warning('Hi there.\nPlease do not do that.')
will just print out:
Warning: hi there.\nPlease do not do that
However, if you pre-format the text using sprintf , then all the escape characters will work. For instance:
warnText = sprintf('Hi there.\nPlease do not do that.');
warning(warnText)
Produces what you want:
Warning: Hi there.
Please do not do that.
A more simple version than EBH had provided is as shown:
str1 = 'text 1';
str2 = 'text 2';
str3 = 'etc.';
str = sprintf('\n%s \n%s \n%s \n',str1,str2,str3);
warning(str)

matlab text read and write %s character (without escaping)

Dear All (with many thanks in advance),
The following script has trouble reading (and therefore writing) the %s character in the file 'master.py'.
I get that matlab thinks the %s is an escape character, so perhaps an option is to modify the terminator, but I have found this difficult.
(EDIT: Forgot to mention the file master.py is not in my control, so I can't modify the file to %%s for example).
%matlab script
%===============
fileID = fopen('script.py','w');
yMax=5;
fprintf(fileID,'yOverallDim = %d\n', -1*yMax);
%READ IN "master.py" for rest of script
fileID2 = fopen('master.py','r');
currentLine = fgets(fileID2);
while ischar(currentLine)
fprintf(fileID,currentLine);
currentLine = fgets(fileID2);
end
fclose(fileID);
fclose(fileID2);
The file 'master.py' looks like this (and the problem is on line 6 'setName ="Set-%s"%(i+1)':
i=0
for yPos in range (0,yOverallDim,yVoxelSize):
yCoordinate=yPos+(yVoxelSize/2) #
for xPos in range (0,xOverallDim,xVoxelSize):
xCoordinate=xPos+(xVoxelSize/2)
setName ="Set-%s"%(i+1)
p = mdb.models['Model-1'].parts['Part-1']
# p = mdb.models['Model-1'].parts['Part-2']
c = p.cells
cells = c.findAt(((xCoordinate, yCoordinate, 10.0), ))
region = p.Set(cells=cells, name=setName)
p.SectionAssignment(region=region, sectionName='Section-1', offset=0.0, offsetType=MIDDLE_SURFACE, offsetField='', thicknessAssignment=FROM_SECTION)
i+=1
In the documentation of fprintf you'll find this:
fprintf(fileID,formatSpec,A1,...,An) applies the formatSpec to all elements of arrays A1,...An in column order, and writes the data to a text file.
So in your function fprintf uses currentLine as format specification, resulting in an unexpected output for line 6. Correct application of fprintf by providing a formatSpec, fixes this issue and doesn't require any replace operations:
fprintf(fileID, '%s', currentLine);
Your script has no trouble reading the % characters correctly. The "problem" is with fprintf(). This function correctly interpretes the percent signs in the string as formatting characters. Therefore, I think you have to manually escape every single % character in your currentLine string:
currentLine = strrep(currentLine, '%', '%%');
At least, it worked when I checked it on your example data.
Thanks applesoup for identifying my fundamental oversight - the problem is in the fprintf - not in the file read
Thanks serial for enhancing the fprintf

How to read a string containing a comma and an at sign with textread?

My prototype data line looks like this:
(1) 11 July England 0-0 Uruguay # Wembley Stadium, London
Currently I'm using this:
[no,dd,mm,t1,p1,p2,t2,loc]=textread('1966.txt','(%d) %d %s %s %d-%d %s # %[%s \n]');
But it gives me the following error:
Error using dataread
Trouble reading string from file (row 1, field 12) ==> Wembley Stadium, London\n
Error in textread (line 174)
[varargout{1:nlhs}]=dataread('file',varargin{:}); %#ok<REMFF1>
So it seems to have trouble with reading a string that contains a comma, or it's the at sign that causes trouble. I read the documentation thoroughly but nowhere does it mention what to do when you have special characters such as # or if you want to read a string that contains a delimiter even though it I don't want it recognized as a delimiter.
You want
[no,dd,mm,t1,p1,p2,t2,loc] = ...
textread('1966.txt','(%d) %d %s %s %d-%d %s # %[^\n]');