04 Input and Output
04 Input and Output
-->x
x =
2.3
In a program, on the other hand, the appearance of a variable name does not produce printed
output. Moreover, even with console I/O we may want more control over the output format. We
also need a way for a program to display values and ask for input, either from the user or from a
file. There are various ways to approach this. We start with the simplest.
-->disp([x,y])
2.3 4.1
This works from within a program also. You can also combine it with the string() function
(num2str() in Matlab) and the string concatenate operation. This creates one long string as in
the following
Exercise 1:
-->disp(x)
3.2
and strings
-->fname = input('output file : ')
output file : 'test.txt'
fname =
test.txt
Here's a little snippet of code that prompts the user for an array of data and prints the average
value.
z = input('enter a 1-by-n array of numbers : ');
disp('the average value is '+string(mean(z)));
this produces
enter a 1-by-n array of numbers : [1,2,3,4,5,6]
the average value is 3.5
Exercise 2:
The save command saves all variable names and values, essentially your entire Scilab session.
You can exit Scilab and in a later session use the load command to recove these saved values.
-->load('test.dat')
-->A
A =
1. 2.
3. 4.
-->x
x =
1. 2. 3. 4. 5.
-->s
s =
hello there
This works the same in Matlab, except the file name should not have an extension (for example
'test') as Matlab appends the .mat extension automatically. You can explicitly specify the
variables you want to save/load as in
-->save('Ax.dat','A','x'); //Scilab
>> save('Ax','A','x'); %Matlab
This saves only the variables A and x. To load one or more specific variables you do the
following
-->load('Ax.dat','A'); //Scilab
>> load('Ax','A'); %Matlab
Exercise 3:
3 Formatted I/O
Scilab/Matlab implement versions of the C fprintf and sprintf functions for formatted output.
fd is a file descriptor and format is a string that specifies how you want the output formatted.
var_1 through var_n are the variables you want displayed. In Scilab the number 6 is the file
descriptor for the console. This is also stored in the protected variable %io(2).
An example is
-->fd = %io(2);
-->x = 1.23;
-->mfprintf(fd,'the value of x is %f\n',x);
the value of x is 1.230000
The \n symbol denotes a "new line." If you omit this then subsequent mfprintf commands
will be appended to the same line. Consider the following.
mfprintf(fd,'the value of x is %f',x);
mfprintf(fd,' and y is %f\n',y);
produces
the value of x is 1.230000 and y is 3.210000
Finally, if you want to control the precise format of the numerical output, the syntax for a
floating point number is %m.nf where m is the total number of spaces (you need one for the
decimal point and you might need one for the sign) and n is the number of decimal places. For
example
-->mfprintf(fd,'%4.2f\n',x);
1.23
-->mfprintf(fd,'%6.2f\n',x);
1.23
-->mfprintf(fd,'%6.3f\n',x);
1.230
For %d and %s formats you can use the syntax %md or %ms where m is the total number of
spaces to be displayed. Note that if you don't allocate enough, the full value will be printed
anyway. If you allocate "too much" then blank space will be added. In the following example we
generate a formatted table of trig values.
N = 4;
x = linspace(0,%pi/2,N);
y = sin(x);
z = cos(x);
mfprintf(fd,'\n'); //creates blank line at start
mfprintf(fd, '%6s %6s %6s\n','x','sin','cos');
for i=1:N
mfprintf(fd,'%6.3f %6.3f %6.3f\n',x(i),y(i),z(i));
end
Note the mfprintf(fd,'\n'); statement used to clear any previously "open" lines of
output. The output is
x sin cos
0.000 0.000 1.000
0.524 0.500 0.866
1.047 0.866 0.500
1.571 1.000 0.000
-->mfprintf(fd,'%-3d\n',k);
5
-->mfprintf(fd,'%03d\n',k);
005
The format %-3d causes the output to be left aligned as opposed to the default right alignment.
The format %03d causes the output to be right aligned but all remaining space to the left is filled
with zeros.
In keeping with the “vectorized” nature of Scilab/Matlab, the mfprintf (and fprintf)
function is also vectorized. For example
-->x = 1:3
x =
1. 2. 3.
-->mfprintf(fd,'%d %d %d\n',x)
1 2 3
Scilab/Matlab recognizes that x is an array. It fills in the 3 %d formats with x(1), x(2) and
x(3). Now consider this
A = [1,2;3,4];
-->mfprintf(fd,'%f %f\n',A)
1.000000 2.000000
3.000000 4.000000
mfprintf repeats itself for each row of matrix A. In addition to mfprintf there is a Scilab
function mprintf that does not require the file descriptor argument and prints directly to the
console.
-->x = 2;
-->mprintf('%f %f %f\n',x,x^2,x^3)
2.000000 4.000000 8.000000
The advantage of using mfprintf with fd = %io(2) for console output is that it is very
simple to modify your code to output to a file. You merely need to assign the fd variable using
the mopen command described below.
Exercise 4:
This has created a string with the value of k embedded. An example where this is very useful is
in creating frames for an animation where k goes from 1 to N and each file output is a single
frame.
This opens the file test.txt for output in the current directory. If it doesn't exist it is created.
If it does exist is it overwritten. The 'wt' notation indicates that we are opening this file for
writing in text format. You can also write in binary format, but we won't cover that. 'at'
designates a text file opened for appending. To open a text file for reading we use 'rt'.
[fd,err] = mopen('test.txt','rt');
The resulting file descriptor fd can be used to refer to the file and err is an error flag. It is zero
or empty if the open process worked properly and non-zero otherwise. You will get an error if
you try to open a file for reading that doesn't exist, or a file for writing in a directory where you
don't have write permission. Good programming practice is to always include error checking. For
example
[fd,err] = mopen('test.txt','rt');
if (err)
error('cannot open test.txt');
end
If there is an error opening 'test.txt' you will get a message and then Scilab will exit using
the error() function. It is very important to always close a file when you have finished
reading or writing. This is done with the mclose(fd) command (fclose(fd) in Matlab).
Here's an example
A = [1,2;3,4];
[fd,err] = mopen('A.txt','wt');
if (err)
error('cannot open file');
end
mfprintf(fd,'%f %f\n',A);
mclose(fd);
A common source of errors when trying to open a file for reading is that the file does not exist. A
way to test for this is using the isfile() command. In the following example a file named
'test.txt' exists the current directory but a file named 'test2.txt' does not.
-->isfile('test.txt')
ans =
T
-->isfile('test2.txt')
ans =
F
Exercise 5:
We can read these numbers into a vector x as follows (note that for compactness we are not
including error checking for the mopen command).
[fd,err] = mopen('data.txt','rt');
[n,x] = mfscanf(6,fd,'%d');
mclose(fd);
disp(x');
1. 2. 3. 4. 5. 6.
Variable n indicates the number of successful reads. It is -1 if the end of file was reached before
all desired data were read. The 6 tells mfscanf to read six times in the %d format. These are
-->x'
ans = 1. 2. 3.
-->y'
ans = 4. 5. 6.
This reads 3 numbers and assigns them to x, then another 3 numbers are read and assigned to y.
In Matlab the ordering is slightly different
[fd,err] = fopen('data.txt','rt');
[n,x] = fscanf(fd,'%d',3);
[n,y] = fscanf(fd,'%d',3);
fclose(fd);
Here another example in Scilab. This time the file data.txt looks like this
east 2 23.75
west 4 -94.5
south 1 8.2
north 3 -7.9
fill the arrays s, d and x with the corresponding string, decimal and floating point entries
-->s'
ans = !east west south north !
-->d'
ans = 2. 4. 1. 3.
-->x'
ans = 23.75 - 94.5 8.1999998 - 7.9000001
1
2
3
What do we do if we know the file contains some numbers but we don't know how many? One
way to read all the available numbers in the file is to read them one at a time followed by a check
for an end-of-file condition using the meof function (feof in Matlab). This returns a non-zero
value if the last input operation reached the end of the file. Here's an example of how we can use
this in a program.
[fd,err] = mopen('test.txt','rt');
i = 1; //use i for an array index
while (~meof(fd)) //while we haven't reach the end of the file
x(i) = mfscanf(fd,'%f'); //read the next number
i = i+1; //increment the array index
end
mclose(fd);
disp(x');
We open the file and then as long as we have not reached the end-of-file condition we read a
single number into an element of an array x, increment the array index i and try again. This
reads in the values 1, 2, 3 and 4 then stops when the end of the file is reached. One thing to
notice is that Scilab ignores the “white space” in the file (spaces, tabs and line-feed characters)
and only looks for printable characters.
Exercise 6:
There are many other input/output functions. In the Scilab Help Browser see the sections titled
Files : Input/Output functions
Input/Output functions
5 Spreadsheet support
Scilab/Matlab can read and write data in spreadsheet format. We will only consider spreadsheets
with numeric data and using comma-delimited text format (csv files). Suppose the spreadsheet
ss.csv looks like
1. 2. 3.
4. 5. 6.
It is possible to specify a separator other than a comma and to read and write strings. See the
Spreadsheet section of the help menu for more information.